始终在NHibernate中加密映射

时间:2018-01-30 09:15:38

标签: sql-server nhibernate always-encrypted

目前,我正在使用 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个文件中定义哪种映射?

1 个答案:

答案 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.cs146,您会看到以下评论:

  

//不要使用来自的数据覆盖字符串的默认长度   SqlType,因为LIKE表达式需要
  //更大的列。   https://nhibernate.jira.com/browse/NH-3036

那么我们如何才能解决这个问题呢?我们可以为Nhibernate创建一个新的Driver,用于定义准确的参数长度。 (当然,如果你不关心NHibernate喜欢的表达方式)。 (我在%%

上使用了这种方法
NHiberate 3.x