Lek*_*001 4 sql azure-keyvault always-encrypted .net-core-3.1 ef-core-3.1
我有一个 .Net Core 3.1 项目,使用 EF Core 访问 Azure SQL 数据库中的数据。我目前正在尝试在某些敏感列上实现始终加密功能。
我成功加密了该列,将主密钥存储在 Azure Key Vault 中,我在其中创建了可以访问此密钥的应用程序注册。
我使用此视频来实现此目的:https://www.youtube.com/watch ?v=POLTjo7GpRc
然后,我能够在 C# 代码中检索主密钥并启动 SQL 查询,即从加密表中进行简单的选择。
我可以以明文形式检索加密列(解密),很好。
我现在的问题是,如何配置 EF Core 以检索 Azure Key Vault 中的主密钥并返回实体中的解密值?Sql 查询可以工作,但我不知道如何使其与 EF Core 一起工作。
多谢!
根据我的测试,如果您使用 Azure Key Vault 为 SQL Server 配置了 Always Encrypted,请Microsoft.EntityFrameworkCore.SqlServer
在您的应用程序中使用 EF core 实现。
例如
创建 Azure AD 应用程序并在 Azure 密钥保管库中配置该应用程序的访问策略。
配置应用程序
A。安装SDK
ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.1" />
<PackageReference Include="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" Version="1.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="5.2.7" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.1" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
b. 创建模型
public class Patient
{
public int PatientId { get; set; }
public string SSN { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
C。创建数据库上下文
public class TestContext :DbContext
{
private static Boolean isInitialized;
public TestContext(DbContextOptions<TestContext> options) : base(options)
{
if(! isInitialized) { InitializeAzureKeyVaultProvider(); isInitialized = true; }
}
public DbSet<Patient> Patients { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Patient>().ToTable("Patients");
}
private static string clientId = "the ad application appid";
private static string clientSecret = "the ad application appSecret";
private static ClientCredential _clientCredential;
private static void InitializeAzureKeyVaultProvider()
{
_clientCredential = new ClientCredential(clientId, clientSecret);
SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
}
private async static Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, _clientCredential);
if (result == null)
throw new InvalidOperationException("Failed to obtain the access token");
return result.AccessToken;
}
}
Run Code Online (Sandbox Code Playgroud)
d. 注册 DbContext。在 中添加以下代码Startup.cs
。
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TestContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
}
e. 在appsettings.json中添加connectionString
{
"ConnectionStrings": {
"DefaultConnection": "Server=tcp:<your server name>.database.windows.net,1433;
Initial Catalog=<db name>;
Persist Security Info=False;
User ID=<user>;
Password=<password>;
Column Encryption Setting=enabled;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
},
...
Run Code Online (Sandbox Code Playgroud)欲了解更多详情,请参阅
https://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro?view=aspnetcore-3.1