目前,我正在使用 SQL Server 2016 来充分利用Always Encrypted
功能。我应该加密几列。我用SQL Server加密了这些列。 NHibernate
可以轻松地从SQL Server
读取数据,但是当它尝试在数据库中插入数据时,它会抛出如下所示的行为:
操作数类型冲突:nvarchar(4000)加密(encryption_type = ' DETERMINISTIC',encryption_algorithm_name = ' AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name = ' CEK_Auto1',column_encryption_key_database_name =' EncTest')是 与使用(encryption_type =。)加密的nvarchar(250)不兼容 ' DETERMINISTIC',encryption_algorithm_name = ' AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name = ' CEK_Auto1',column_encryption_key_database_name =' EncTest')
这是我在NHibernate
中的特定列的列映射:
<column name="DisableTxt" length="100" sql-type="NVarChar" />
我应该在hbm
个文件中定义哪种映射?
答案 0 :(得分:1)
我找到了解决此问题的方法,首先我想说明为什么Connection
无法在NHibernate
功能中使用Encrypted Columns
:
当我们在连接字符串中启用Always Encrypted
时,AlwaysEncrypted
会在任何数据库操作之前自动执行store procedure ADO.NET
,以确定哪些参数对应于受保护的数据库列使用“始终加密”功能。此sp对字段的长度敏感,如果指定的参数长度不等于列长度,SQL Server将在下面给出错误:
操作数类型冲突:nvarchar(4000)加密(encryption_type = 'DETERMINISTIC',encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name = 'CEK_Auto1',column_encryption_key_database_name ='EncTest')是 与使用(encryption_type =。)加密的nvarchar(250)不兼容 'DETERMINISTIC',encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name = 'CEK_Auto1',column_encryption_key_database_name ='EncTest')
这是因为sp_describe_parameter_encryption
始终为NHibernate
列定义4000
的参数大小(如果列长度不是NVarchar
)。所以想象一下,我们有一个长度为NVarchar(max)
的列但30
为指定列定义了一个长度为NHibernate
的参数。为什么4000
会这样做?
如果您查看NHibernate
来源SqlClientDriver.cs
行146,您会看到以下评论:
//不要使用来自的数据覆盖字符串的默认长度 SqlType,因为LIKE表达式需要
//更大的列。 https://nhibernate.jira.com/browse/NH-3036
那么我们如何才能解决这个问题呢?我们可以为Nhibernate
创建一个新的Driver
,用于定义准确的参数长度。 (当然,如果你不关心NHibernate
喜欢的表达方式)。 (我在%%
)
NHiberate 3.x