SSMS查询Always Encrypted加密列解密失败,如何配置密钥并查看明文?
我有一个包含加密列的数据库,Java项目中的数据源配置如下:
@Bean(name = "azureLocalDataSource") public DataSource localDataSource() throws IOException { log.debug("Initializing Azure Sql DEV DataSource"); this.setJdbcUrl(dataSourceUrl); this.addDataSourceProperty("columnEncryptionSetting","Enabled"); this.addDataSourceProperty("keyStoreAuthentication", "JavaKeyStorePassword"); this.addDataSourceProperty("keyStoreLocation",new ClassPathResource(keyStoreLocation).getFile().getAbsolutePath()); this.addDataSourceProperty("keyStoreSecret",keyStoreSecret); this.addDataSourceProperty("defaultAutoCommit", false); this.addDataSourceProperty("trustServerCertificate", true); return new HikariDataSource(this); }
在开启Always Encrypted的SSMS中执行查询语句 SELECT customer_id FROM [schema1].[rewards_points_issuance_recon] 时,出现以下错误:
Msg 0, Level 11, State 0, Line 0 Failed to decrypt column 'customer_id'. Msg 0, Level 11, State 0, Line 0 Failed to decrypt a column encryption key. Invalid key store provider name: 'MSSQL_JAVA_KEYSTORE'. A key store provider name must denote either a system key store provider or a registered custom key store provider. Valid system key store provider names are: 'MSSQL_CERTIFICATE_STORE', 'MSSQL_CNG_STORE', 'MSSQL_CSP_PROVIDER'. Valid (currently registered) custom key store provider names are: 'AZURE_KEY_VAULT'. Please verify key store provider information in column master key definitions in the database, and verify all custom key store providers used in your application are registered properly.
请问:
- 我可以在哪里指定密钥库(keystore)的位置和密码?
- 如何在SSMS中显示该列的明文值?
一、密钥库位置和密码的配置位置
问题出在SSMS默认不识别MSSQL_JAVA_KEYSTORE这个密钥库提供者——你的Java应用用的是Java KeyStore,但SSMS只默认支持系统内置的几个提供者(比如证书存储、CNG存储)和Azure Key Vault。要在SSMS里用Java KeyStore,得先注册自定义密钥库提供者,再配置参数:
注册Java KeyStore的SSMS扩展
先获取Microsoft官方的SqlColumnEncryptionJavaKeyStoreProvider扩展DLL(一般在SQL Server JDBC驱动的配套工具包里),然后用PowerShell注册:Register-SqlColumnEncryptionKeyStoreProvider -Name "MSSQL_JAVA_KEYSTORE" -AssemblyPath "你的DLL文件绝对路径" -ClassName "Microsoft.SqlServer.Management.SqlColumnEncryptionJavaKeyStoreProvider.JavaKeyStoreProvider"在SSMS连接时配置密钥库参数
注册完后,连接数据库时要指定密钥库信息:- 打开SSMS连接窗口,点击选项 >>
- 切换到Always Encrypted标签页,勾选启用Always Encrypted(列加密)
- 点击密钥库设置,在弹出的窗口中:
- 密钥库类型选择
MSSQL_JAVA_KEYSTORE - 输入密钥库文件的绝对路径(和你Java配置中的
keyStoreLocation一致) - 输入密钥库密码(对应Java配置里的
keyStoreSecret)
- 密钥库类型选择
- 保存设置后重新连接数据库
二、在SSMS中查看明文值
完成密钥库配置后,按以下步骤就能看到明文:
确保连接启用Always Encrypted
连接数据库时必须勾选启用Always Encrypted(列加密),否则SSMS不会尝试解密加密列。直接执行查询
重新连接后,执行SELECT customer_id FROM [schema1].[rewards_points_issuance_recon],SSMS会自动用你配置的Java KeyStore解密customer_id列,返回明文结果。异常排查:检查列主密钥定义
如果还是报错,先确认数据库中的列主密钥提供者名称是否和你注册的一致,执行以下查询验证:SELECT name, key_store_provider_name FROM sys.column_master_keys确保
key_store_provider_name的值是MSSQL_JAVA_KEYSTORE,不一致的话需要修改列主密钥定义。
内容的提问来源于stack exchange,提问作者techie11

