Sql server Azure Sql列级加密错误-无法使用密钥存储提供程序对列加密密钥进行解密:';AZURE#u KEY#u VAULT';

Sql server Azure Sql列级加密错误-无法使用密钥存储提供程序对列加密密钥进行解密:';AZURE#u KEY#u VAULT';,sql-server,encryption,azure-keyvault,azure-managed-identity,always-encrypted,Sql Server,Encryption,Azure Keyvault,Azure Managed Identity,Always Encrypted,我正在使用API的POC向SQL数据库存储/检索一些敏感信息。API使用EF核心进行DB操作。我已使用Azure KeyVault provider配置了列级加密。 正在KeyVault中生成主密钥 private static void InitializeAzureKeyVaultProvider() { SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new Sql

我正在使用API的POC向SQL数据库存储/检索一些敏感信息。API使用EF核心进行DB操作。我已使用Azure KeyVault provider配置了列级加密。 正在KeyVault中生成主密钥

private static void InitializeAzureKeyVaultProvider()
    {
        SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
          new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);

        Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
          new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();

        providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
        SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
    }

    private static async Task<string> GetToken(string authority, string resource, string scope)
    {
        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/").ConfigureAwait(false);
        return accessToken;
    }
EF配置参考

我需要使用托管标识从KeyVault访问加密主密钥。下面是使用Microsoft.Azure.Services.AppAuthentication库初始化KeyVault提供程序并获取令牌以访问KeyVault的代码

private static void InitializeAzureKeyVaultProvider()
    {
        SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
          new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);

        Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
          new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();

        providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
        SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
    }

    private static async Task<string> GetToken(string authority, string resource, string scope)
    {
        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/").ConfigureAwait(false);
        return accessToken;
    }
private static void InitializeAzureKeyVaultProvider()
{
SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider=
新的SqlColumnEncryptionAzureKeyVaultProvider(GetToken);
词典提供者=
新字典();
添加(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName,azureKeyVaultProvider);
注册表列加密密钥复制器(提供程序);
}
私有静态异步任务GetToken(字符串权限、字符串资源、字符串范围)
{
var azureServiceTokenProvider=新azureServiceTokenProvider();
string accessToken=await azureServiceTokenProvider.GetAccessTokenAsync(“https://management.azure.com/“”。配置等待(错误);
返回accessToken;
}
正在成功生成访问令牌

除了主密钥外,我还在KeyVault中存储连接字符串,并使用托管标识配置KeyVault提供程序以从KeyVault检索连接字符串

private static void InitializeAzureKeyVaultProvider()
    {
        SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
          new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);

        Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
          new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();

        providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
        SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
    }

    private static async Task<string> GetToken(string authority, string resource, string scope)
    {
        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/").ConfigureAwait(false);
        return accessToken;
    }

我在Azure中部署了Api应用程序并启用了标识。我使用此系统生成的ObjectId添加KeyVault访问策略,以允许Api访问KeyVault。 我已经为密钥提供了所需的权限,例如get、wrapKey、unwrapKey、sign、verify和list

现在我可以访问连接字符串并能够连接到数据库。但当我试图将记录保存到数据库中时,我发现了以下错误

看起来我无法使用生成的令牌访问KeyVault。我遗漏了什么吗?。请帮忙

Microsoft.EntityFrameworkCore.DbUpdateException HResult=0x80131500 消息=更新条目时出错。有关详细信息,请参见内部异常。 Source=Microsoft.EntityFrameworkCore.Relational 堆栈跟踪: 在Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection) 在Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable
1 commandBatches,IRelationalConnection连接)在Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList
1个条目) 在Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList
1 entriesToSave)在Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(DbContext),布尔接受ChangesOnSuccess)在Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](t状态,Func
3操作,Func`3验证成功) 位于Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(布尔接受更改成功) 在Microsoft.EntityFrameworkCore.DbContext.SaveChanges(布尔接受更改成功) 在Microsoft.EntityFrameworkCore.DbContext.SaveChanges()中 在D:\Data\Projects\DbEncryptionApi\DbEncryptionApi\Controllers\MedicalController.cs中的DbEncryptionApi.Controllers.MedicalController.SavePatientRecord(PatientTo patient)中 位于Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(对象目标,对象[]参数) 位于Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper映射器、ObjectMethodExecutor执行器、对象控制器、对象[]参数) 在Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()中 位于Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(状态和下一步、范围和范围、对象和状态、布尔值和isCompleted) 在Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()上

此异常最初是在此调用堆栈中引发的: [外部代码]

内部异常1: SqlException:无法使用密钥存储提供程序“AZURE\u key\u VAULT”解密列加密密钥。验证数据库中列加密密钥及其列主密钥的属性。加密列加密密钥的最后10个字节是:“C6-C8-F6-58-A0-DE-6F-68-73-9F”。 发生了一个或多个错误。(操作返回无效的状态代码“Unauthorized”)

内部例外2:
KeyVault ErrorException:操作从错误中返回了无效的状态代码“Unauthorized”

。您可能没有正确配置列加密密钥并将其链接到KeyVault中的主密钥

private static void InitializeAzureKeyVaultProvider()
    {
        SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
          new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);

        Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
          new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();

        providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
        SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
    }

    private static async Task<string> GetToken(string authority, string resource, string scope)
    {
        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/").ConfigureAwait(false);
        return accessToken;
    }
我建议您检查数据库中列加密的设置—可能是第一步使用向导验证KeyVault的设置