sql-server - Azure Sql 列级加密错误 - 无法使用密钥存储提供程序解密列加密密钥:“AZURE_KEY_VAULT”
问题描述
我正在使用 API 的 POC 来存储/检索 SQL 数据库的一些敏感信息。API 使用 EF 核心进行数据库操作。我已使用 Azure KeyVault 提供程序配置列级加密。主密钥正在 KeyVault 中生成。
EF 配置参考
我需要使用托管身份从 KeyVault 访问加密 MasterKey。下面是初始化 KeyVault 提供程序并使用 Microsoft.Azure.Services.AppAuthentication 库获取令牌令牌以访问 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 中,并使用托管标识配置了 KeyVault 提供程序以从 KeyVault 检索连接字符串。
https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-3.1
我在 Azure 中部署了 Api App 并启用了 Identity。我使用这个系统生成的 ObjectId 来添加 KeyVault 访问策略以允许 Api 访问 KeyVault。我已为 get、wrapKey、unwrapKey、sign、verify、list 等密钥提供了所需的权限
现在我可以访问连接字符串并能够连接到数据库。但是当我试图将记录保存在数据库中时,我遇到了错误。
看起来使用生成的令牌我无法访问 KeyVault。我错过了什么吗?请帮忙。
Microsoft.EntityFrameworkCore.DbUpdateException HResult=0x80131500 消息=更新条目时出错。有关详细信息,请参阅内部异常。Source=Microsoft.EntityFrameworkCore.Relational StackTrace:在 Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager 的 Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable 1 commandBatches, IRelationalConnection connection) at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList
1 entries) 的Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection 连接) .SaveChanges(IList1 entriesToSave) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(DbContext _, Boolean acceptAllChangesOnSuccess) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func
3 操作,Func`3 verifySucceeded) 在 Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess) 在 Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess) 在 Microsoft.EntityFrameworkCore.DbContext.SaveChanges() 在 DbEncryptionApi.Controllers .MedicalController.SavePatientRecord(PatientDto patient) 在 Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters) 中的 D:\Data\Projects\DbEncryptionApi\DbEncryptionApi\Controllers\MedicalController.cs:line 34。 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker 上的 AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,对象控制器,Object[] 参数)。InvokeActionMethodAsync() 在 Microsoft.AspNetCore.Mvc.Infrastructure.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
此异常最初是在此调用堆栈中引发的:[外部代码]
内部异常 1:SqlException:无法使用密钥存储提供程序解密列加密密钥:“AZURE_KEY_VAULT”。验证数据库中列加密密钥及其列主密钥的属性。加密列加密密钥的最后 10 个字节为:'C6-C8-F6-58-A0-DE-6F-68-73-9F'。发生一个或多个错误。(操作返回无效状态代码“未授权”)
内部异常 2:KeyVaultErrorException:操作返回无效状态代码“未授权”
解决方案
从错误看来,您可能没有正确配置列加密密钥并将其链接到 KeyVault 中的主密钥。
我建议您查看数据库中列加密的设置 - 作为第一步,也许使用向导来验证 KeyVault 的设置。
推荐阅读
- sql - Spark-SQL - 根据日期间隔生成多行
- python - 使用 .loc 时数据框排序不适用
- javascript - 如何将有关从通道获取的消息的信息放入 JSON 文件?
- r - 计算两个列表之间的皮尔逊系数
- python - 如何实现通过嵌套字典找到关键路径的函数max_leaf_path(d)?
- c# - ASP.NET REST API 没有实体框架但有 DAO 的
- javascript - 无法从手机加载 Ionic 项目
- spring-mvc - 在名称为“newApp”的 DispatcherServlet 中找不到具有 URI [/demoApp/add] 的 HTTP 请求的映射
- events - SDL2 只返回第一个注册的 UserEvent
- java - Android Searchview过滤器recyclerview volley实现