将 Always Encrypted 与 EF Core 结合使用并将主密钥存储在 Azure Key Vault 中

Using Always Encrypted with EF Core and storing Master Key in Azure Key Vault

我有一个 .Net Core 3.1 项目使用 EF Core 访问 Azure SQL 数据库中的数据。我目前正在尝试在某些敏感列上实施 Always Encrypted 功能。

我成功加密了该列,将主密钥存储在 Azure Key Vault 中,我在其中创建了一个可以访问该密钥的应用程序注册。

我使用这个视频来实现这个:https://www.youtube.com/watch?v=POLTjo7GpRc

然后我能够在我的 c# 代码中检索主密钥并启动一个 SQL 查询,一个简单的 select 来自加密的 table.

我可以以明文(解密)的形式检索加密列,没问题。

我现在的问题是,如何配置 EF Core 以在 Azure Key Vault 中检索我的主密钥并 return 在我的实体中检索解密值? Sql 查询有效,但我不知道如何使其与 EF Core 一起使用。

非常感谢!

根据我的测试,如果您已经为您的 SQL 服务器配置了 Always Encrypted 和 Azure 密钥保管库,请使用 Microsoft.EntityFrameworkCore.SqlServer 在您的应用程序中实施 EF 核心。

例如

  1. Configure Always Encrypted

  2. 创建 Azure AD 应用程序并在 Azure 密钥保管库中为该应用程序配置访问策略。

  3. 配置应用程序

    一个。安装 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>
    
    

    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; }
    }
    

    c。创建 DbContext

    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;
       }
    }
    

    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;"
    },
    ...
    

更多详情请参考

https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro?view=aspnetcore-3.1

https://docs.microsoft.com/en-us/sql/connect/ado-net/sql/sqlclient-support-always-encrypted?view=sql-server-ver15