You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET MVC 5中用ErikEJ EF结合Azure KeyVault实现SQL Server Always Encrypted

分步实现ASP.NET MVC 5 + EF6 + SQL Server Always Encrypted + Azure KeyVault

一、确认EF6提供程序配置(已安装ErikEJ.EntityFramework.SqlServer)

  1. 修改web.config中的EF提供程序,替换默认SQL Server提供程序:
    <entityFramework>
      <providers>
        <provider invariantName="Microsoft.Data.SqlClient" 
                 type="ErikEJ.EntityFramework.SqlServer.SqlProviderServices, ErikEJ.EntityFramework.SqlServer" />
      </providers>
    </entityFramework>
    
  2. 更新数据库连接字符串,使用Microsoft.Data.SqlClient并启用列加密:
    <connectionStrings>
      <add name="YourDbContext" 
           connectionString="Server=your-server;Database=your-db;User ID=your-user;Password=your-pass;Column Encryption Setting=Enabled;" 
           providerName="Microsoft.Data.SqlClient" />
    </connectionStrings>
    

二、搭建Azure KeyVault并配置权限

  1. 创建KeyVault:
    • 登录Azure门户,新建KeyVault实例,选择合适区域、定价层,启用软删除和清除保护(强制安全要求)。
  2. 生成列主密钥(CMK):
    • 进入KeyVault的「密钥」菜单,点击「生成/导入」,选择密钥类型为RSA,密钥大小≥2048,设置有效期后保存。
  3. 配置应用访问权限:
    • 注册Azure AD服务主体:在Azure AD的「应用注册」中新建应用,记录客户端ID和客户端密钥(创建密钥时生成)。
    • 回到KeyVault的「访问策略」,点击「添加访问策略」:
      • 密钥权限选择「Get、Unwrap Key、Wrap Key」(满足Always Encrypted的密钥操作需求);
      • 选择主体为刚注册的Azure AD应用;
      • 保存策略。

三、Web应用集成Azure KeyVault(核心步骤)

方式1:使用服务主体(本地开发/非Azure部署)

  1. 安装NuGet包:Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
  2. 在web.config的appSettings中添加Azure AD凭据:
    <appSettings>
      <add key="AzureADTenantId" value="你的Azure AD租户ID" />
      <add key="AzureADClientId" value="你的服务主体客户端ID" />
      <add key="AzureADClientSecret" value="你的服务主体客户端密钥" />
    </appSettings>
    
  3. 在Global.asax.cs的Application_Start中注册KeyVault密钥提供程序:
    using Microsoft.Data.SqlClient;
    using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    
    protected void Application_Start()
    {
        // 初始化KeyVault令牌提供程序
        var tenantId = ConfigurationManager.AppSettings["AzureADTenantId"];
        var clientId = ConfigurationManager.AppSettings["AzureADClientId"];
        var clientSecret = ConfigurationManager.AppSettings["AzureADClientSecret"];
    
        var tokenProvider = new AzureKeyVaultTokenProvider(
            authority: $"https://login.microsoftonline.com/{tenantId}",
            clientId: clientId,
            clientSecret: clientSecret);
    
        // 注册KeyVault作为Always Encrypted的密钥存储
        var azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(tokenProvider);
        SqlConnection.RegisterColumnEncryptionKeyStoreProviders(
            new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>
            {
                { SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider }
            });
    
        // 原有MVC初始化代码
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
    

方式2:使用Azure托管身份(部署到Azure App Service时推荐)

这种方式无需存储客户端密钥,更安全:

  1. 在Azure App Service的「身份」菜单中启用「系统分配」身份。
  2. 在KeyVault的「访问策略」中添加该App Service的身份,授予相同的密钥权限(Get、Unwrap Key、Wrap Key)。
  3. 修改Global.asax.cs中的令牌提供程序:
    var tokenProvider = new ManagedIdentityTokenProvider();
    // 后续注册代码与方式1一致
    

四、数据库与代码适配

  1. 创建列加密密钥(CEK):
    • 使用SSMS连接数据库时,勾选「选项」中的「启用列加密」;
    • 执行SQL创建CEK(关联KeyVault中的CMK):
      CREATE COLUMN MASTER KEY MyCMK
      WITH (
          KEY_STORE_PROVIDER_NAME = 'AZURE_KEY_VAULT',
          KEY_PATH = 'https://your-keyvault-name.vault.azure.net/keys/your-cmk-name/your-key-version'
      );
      
      CREATE COLUMN ENCRYPTION KEY MyCEK
      WITH VALUES (
          COLUMN_MASTER_KEY = MyCMK,
          ALGORITHM = 'RSA_OAEP',
          ENCRYPTED_VALUE = 0x... -- 此值由SSMS自动生成,或通过向导创建
      );
      
    • 或者直接在表设计中,选择需要加密的列,设置「加密类型」为「确定性」或「随机化」,关联CEK后保存。
  2. 代码注意事项:
    • 加密列的LINQ查询避免使用SQL端函数(如LIKE、CONVERT),需在客户端处理逻辑;
    • 确保查询参数为强类型,EF会自动处理加密解密;
    • 避免使用原始SQL查询,若必须使用,需确保参数通过EF上下文传递(自动加密)。

五、测试验证

  • 运行应用,执行读写加密列的操作,确认功能正常;
  • 在SSMS中查看加密列数据,应显示为二进制加密值,无法直接读取;
  • 查看KeyVault的「日志」,确认应用正在调用密钥操作(验证权限配置正确)。

内容的提问来源于stack exchange,提问作者Libin TK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:23:12