16

我正在尝试将 SQL Server 2016 的 Always Encrypted 功能与 .NET Core 一起使用,但似乎(还)无法使用。尝试Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider从 Nuget 导入时,我收到一条错误消息,指出它不兼容:

包 Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider 1.0.201501028 与 netstandard1.6 (.NETStandard,Version=v1.6) 不兼容

关于如何/在哪里获得兼容版本的任何想法?

4

4 回答 4

17

.Net Core 3.1 LTS 现在支持 Always Encrypted。

您必须使用 Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider nuget 包

    Install-Package Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider -Version 1.1.1

确保您有 Keyvault 设置。

要在 VS 中调试您的帐户,您必须拥有足够的权限才能访问密钥库。(发布时,应用程序本身必须具有足够的权限:请参阅https://docs.microsoft.com/en-us/azure/key-vault/managed-identity)仅获取和列出权限可能还不够。

然后在 program.cs :

using Microsoft.AspNetCore.Hosting;
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.AzureKeyVault;
using Microsoft.Extensions.Hosting;
//namespaces etc omitted
 public static IHostBuilder CreateHostBuilder(string[] args) =>
     Host.CreateDefaultBuilder(args)
         .ConfigureAppConfiguration((context, config) =>
         {
             var keyVaultEndpoint = GetKeyVaultEndpoint();
             if (!string.IsNullOrEmpty(keyVaultEndpoint))
             {
                 var azureServiceTokenProvider = new AzureServiceTokenProvider();
                 var keyVaultClient = new KeyVaultClient(
                     new KeyVaultClient.AuthenticationCallback(
                         azureServiceTokenProvider.KeyVaultTokenCallback));
                 config.AddAzureKeyVault(keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
                 SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(new KeyVaultClient.AuthenticationCallback(
                         azureServiceTokenProvider.KeyVaultTokenCallback));
                 SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders: new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase)
                 {
                     { 
                         SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, sqlColumnEncryptionAzureKeyVaultProvider
                     }
                 });                     
             }
         })
         .ConfigureWebHostDefaults(webBuilder =>
         {
             webBuilder.UseStartup<Startup>();
         });
    private static string GetKeyVaultEndpoint() => "https://YOURKEYVAULT.vault.azure.net/";
}

在 StartUp.cs 配置服务中:

using Microsoft.Data.SqlClient;
//Code omitted
services.AddDbContext<EnitiesModel>(options =>
            options.UseSqlServer(new SqlConnection(Configuration.GetConnectionString("EntitiesModel"))));

确保您的连接字符串包含 Column Encryption Setting=Enabled 参数:

 "ConnectionStrings": {
"EntitiesModel": "Server=SOMESERVER.database.windows.net;Database=SOMEDB;Trusted_Connection=False;Encrypt=True;Integrated Security=False;
MultipleActiveResultSets=true;persist security info=True;user id=SOMEDBACCOUNT;password=SOMEPASSWORD;
Column Encryption Setting=enabled;"   
  }

小问题:如果您使用 DB 脚手架,请确保模型连接字符串也具有列加密设置!(如果你没有改变它,它是在带有 VS 警告的脚手架之后的 DBModel 类中的标准)

这应该让你启动并运行......

于 2020-03-03T09:47:02.940 回答
14

免责声明:我是 Microsoft 的项目经理

.NET Core 目前不支持 Always Encrypted。它在我们的路线图上,我们还没有时间表。

现在支持此功能。请参阅下面的答案。

于 2016-12-16T01:22:26.420 回答
6

它现在在.NET Core 3.0 Preview 5中得到支持,它提供了一个支持 Always Encrypted 等的新SqlClient 。有关更多信息,请参阅此评论

对于 Key Vault 提供程序,您需要改用Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider

于 2019-05-08T02:26:15.127 回答
0

来自 Tim 的上述答案的 Program.cs 的变体,但适用于在 Azure App Registration 中注册的应用程序:

namespace Sample
{
   public class Program
   {
       public static void Main(string[] args)
       {
           CreateHostBuilder(args).Build().Run();
       }

       public static IHostBuilder CreateHostBuilder(string[] args) =>
     Host.CreateDefaultBuilder(args)
         .ConfigureAppConfiguration((context, config) =>
         {
             var keyVaultEndpoint = GetKeyVaultEndpoint();
             if (!string.IsNullOrEmpty(keyVaultEndpoint))
             {
                 var azureServiceTokenProvider = new AzureServiceTokenProvider(keyVaultEndpoint);
                 var keyVaultClient = new KeyVaultClient(
                     new KeyVaultClient.AuthenticationCallback(
                         azureServiceTokenProvider.KeyVaultTokenCallback));
                 
                 SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(new KeyVaultClient.AuthenticationCallback(
                         azureServiceTokenProvider.KeyVaultTokenCallback));
                 SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders: new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase)
                 {
                     {
                         SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, sqlColumnEncryptionAzureKeyVaultProvider
                     }
                 });
             }
         })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

       private static string GetKeyVaultEndpoint() => "RunAs=App;AppId=<app ID>;TenantId=<tenant ID>.onmicrosoft.com;AppKey=<app secret>";
   }
 }
于 2020-09-17T00:26:31.520 回答