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

SQL Server Always Encrypted搭配JDBC失效问题求助

Always Encrypted配置验证及插入数据类型冲突问题

背景配置情况

我正在开发企业级应用,需启用Always Encrypted。目前已完成的配置:

数据库端(DBA/生产IT团队)

  • 创建Azure Key Vault
  • 在Azure AD中创建服务主体/应用注册
  • 在KeyPass中注册客户端ID与密钥
  • 在Key Vault层面添加角色分配
  • 通过SSMS生成并执行了Column Master Key(CMK)脚本:
USE [DE_NAME]
/****** Object:  ColumnMasterKey [*****]    Script Date: 23/12/2022 17:30:17 ******/
CREATE COLUMN MASTER KEY [*****]
WITH
(
    KEY_STORE_PROVIDER_NAME = N'AZURE_KEY_VAULT',
    KEY_PATH = N'https://xxxxxxxxx.vault.azure.net/keys/******/####'
)
GO

应用端

  • Spring Boot + Java 8
  • 使用mssql驱动版本:9.2.1.jre8
  • 已将mssql-jdbc_auth-9.2.1.x64.dll与sqljdbc_auth.dll添加至-Djava.library.path
  • 按官方文档配置了Always Encrypted相关连接参数

疑问1:当前数据库是否已完成Always Encrypted配置?

仅创建CMK不代表Always Encrypted配置完成,还需完成以下关键步骤:

  1. 在数据库中创建Column Encryption Key (CEK),并指定使用已创建的CMK进行加密
  2. 对目标表的特定列(比如测试代码中的eee列)设置加密属性,指定加密类型、算法及关联的CEK

测试代码与报错信息

测试插入代码

try (Connection sourceConnection = DriverManager.getConnection("jdbc:sqlserver://server;DatabaseName=db_name;encrypt=true;trustServerCertificate=true;integratedSecurity=true;columnEncryptionSetting=Enabled;keyVaultProviderClientId=xxxxxxxx-xxxx-xxxx-xxxx-xx71xx1axxd3;keyVaultProviderClientKey=XXX7X~XXXMv21mXqXxX4FBi7XoXmxxxXDSZXw")) {
    
    PreparedStatement stmt = sourceConnection.prepareStatement("INSERT INTO Table_name(id, aaa, bbb, ccc, ddd, eee) VALUES (?, ?, ?, ?, ?, ?)");

    stmt.setInt(1, 999999);
    stmt.setString(2, "local_test_0");
    stmt.setInt(3, 989898);
    stmt.setString(4, "local_test_0");
    stmt.setString(5, "local_test_0");
    stmt.setString(6, "local_test_0");// 该列已加密

    stmt.executeUpdate();

} catch (SQLException e) {
    e.printStackTrace();
}

报错信息

com.microsoft.sqlserver.jdbc.SQLServerException: Operand type clash: varchar(12) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK-XXXX-Shared-XX-XX', column_encryption_key_database_name = 'XXXX') collation_name = 'SQL_Latin1_General_CP1_CI_AS' is incompatible with nvarchar(132) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK-XXXX-Shared-XX-XX', column_encryption_key_database_name = 'XXXX')
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:262)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1632)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:602)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:524)

问题核心

插入时出现加密后varchar与nvarchar类型冲突,怀疑驱动未在插入前执行客户端加密,寻求解决方案。


解决方案步骤

1. 补全数据库端Always Encrypted配置

  • 确认已创建CEK:执行以下SQL检查
SELECT * FROM sys.column_encryption_keys

若未创建,需执行类似脚本创建CEK(关联已有的CMK):

CREATE COLUMN ENCRYPTION KEY [CEK-XXXX-Shared-XX-XX]
WITH VALUES
(
    COLUMN_MASTER_KEY = [你的CMK名称],
    ALGORITHM = 'RSA_OAEP',
    ENCRYPTED_VALUE = 加密后的CEK值(由SSMS生成或手动生成)
)
GO
  • 确认目标列的加密配置:执行以下SQL检查eee列的加密属性是否正确
SELECT name, encryption_type, encryption_algorithm_name, column_encryption_key_name 
FROM sys.columns 
WHERE is_encrypted = 1 AND object_id = OBJECT_ID('Table_name')

2. 修复数据类型不匹配问题

报错提示加密后的varchar(12)与nvarchar(132)不兼容,说明参数类型与列定义不匹配:

  • 检查数据库中eee列的类型:若列是varchar类型,在连接字符串中添加sendStringParametersAsUnicode=false,强制驱动将字符串参数按varchar发送,避免默认转成nvarchar
  • 若列是nvarchar类型,改用stmt.setNString(6, "local_test_0")代替setString,确保参数类型与列定义一致

3. 修正连接字符串配置

  • 移除integratedSecurity=true:该参数是Windows身份验证,与服务主体(Azure AD)身份验证冲突,保留keyVaultProviderClientId和keyVaultProviderClientKey即可
  • 确认columnEncryptionSetting=Enabled已正确设置,确保驱动启用客户端加密

4. 验证Key Vault权限与驱动依赖

  • 确认服务主体拥有Azure Key Vault的Crypto User角色权限,确保驱动能获取CMK解密CEK
  • 检查maven依赖:确保mssql-jdbc的依赖正确,9.x版本驱动已集成Azure KV支持,无需额外引入KV依赖,但需确保classpath中无冲突依赖

内容的提问来源于stack exchange,提问作者M-BNCH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:45:31