SQL Server Always Encrypted 与 .NET Core 不兼容
Posted
技术标签:
【中文标题】SQL Server Always Encrypted 与 .NET Core 不兼容【英文标题】:SQL Server Always Encrypted with .NET Core not compatible 【发布时间】:2017-04-23 00:22:48 【问题描述】:我正在尝试将 SQL Server 2016 的 Always Encrypted 功能与 .NET Core 一起使用,但似乎(还)无法使用。尝试从 Nuget 导入 Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider
,我收到一条错误消息,指出它不兼容:
包 Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider 1.0.201501028 与 netstandard1.6 (.NETStandard,Version=v1.6) 不兼容
关于如何/在哪里获得兼容版本的任何想法?
【问题讨论】:
目前正在这里跟踪:github.com/aspnet/EntityFrameworkCore/issues/9193 【参考方案1】:.Net Core 3.1 LTS 现在支持始终加密。
您必须使用 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;"
小问题:如果您使用数据库脚手架,请确保模型连接字符串也具有列加密设置! (如果你没有改变它,它是标准的 DBModel 类在脚手架后带有 VS 警告)
这应该让你启动并运行......
【讨论】:
您知道是否可以将其与带有应用注册的密钥保管库一起使用?我正在开发一个将部署在 IIS 而不是 Azure 中的应用程序。所以我没有应用服务。但我正在使用 keyvaults 来存储连接字符串和令牌。所以我在 Azure 中有一个可以访问密钥保管库的应用程序注册。应用注册不支持 MSI,所以我不能使用你的方法。但我也找不到我应该如何让它在我的情况下工作。 也许通过应用配置? docs.microsoft.com/en-us/azure/azure-app-configuration/… 感谢您的建议。我可以通过设置 SqlColumnEncryptionAzureKeyVaultProvider 来获取令牌,方法是使用应用注册的客户端 ID 和密钥以及 ActiveDirectory ClientCredential 类来获取令牌。 我已经阅读了数十页文档和示例,试图让基于 azure 的列加密与 EF 一起使用。这可能是唯一一个能做到这三个方面的例子。 +1。 要补充一点:Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 与 Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider 不一样 大多数过时的文档使用的是 .SqlServer 命名空间,这是我的问题的一半.【参考方案2】:免责声明:我是 Microsoft 的项目经理
.NET Core 目前不支持始终加密。它在我们的路线图上,我们还没有时间表。
现在支持。请参阅下面的答案。
【讨论】:
对于那些感兴趣的人,类似的Q/A在这里:***.com/questions/41175489/… @Jakub Szymaszek - Microsoft 现在怎么样,有没有关于这个问题的新更新? 现在呢? 这个问题有什么更新吗?我认为这是 MS 在赶上框架更新时留下的主要安全问题,并且它与其他产品的组织性不好。 Mocrosoft.Data.SqlClient 1.1 发布后有什么更新吗? (youtube.com/watch?v=zhzRzRBDTyE)【参考方案3】:现在 .NET Core 3.0 Preview 5 支持它,它提供了一个新的 SqlClient 支持 Always Encrypted 等。请参阅此comment 了解更多信息。
对于 Key Vault 提供程序,您需要改用 Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider。
【讨论】:
虽然这不是 Key Vault 提供程序,但我认为 SqlClient 对列加密的支持确实使他们能够完成 Key Vault 提供程序的工作。 Key Vault 提供程序也在 2 个月前更新:nuget.org/packages/… 支持 .NET Core 2.1 及更高版本。【参考方案4】:上面 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>";
【讨论】:
以上是关于SQL Server Always Encrypted 与 .NET Core 不兼容的主要内容,如果未能解决你的问题,请参考以下文章
Windows Server 2012搭建SQL Server Always On踩坑全记录
SQL SERVER ALWAYS ON 之 添加新的同步数据库