2

我们有一个数据库,其中包含一些加密列(此处描述的对称密钥)。我正在尝试使用老式 Nhybernate 2.1.2.4 在旧版应用程序中映射这些表。

我以为我可以使用公式映射加密列,如下所示:

<property name="Name" column="Name">
  <formula>
    OPEN SYMMETRIC KEY MyKey DECRYPTION BY CERTIFICATE MyCert
    SELECT CONVERT(NVARCHAR(150), DECRYPTBYKEY(Name)) AS Name FROM [Company] WHERE [Company].[Id] = Id
  </formula>
</property>

不幸的是,这不起作用,因为我不允许在那里使用 open 语句。我可以通过尝试在纯 SQL 中重现该问题:

SELECT 
    Company.Id, 
      (OPEN SYMMETRIC KEY MyKey DECRYPTION BY CERTIFICATE MyCert 
      SELECT CONVERT(NVARCHAR(150), DECRYPTBYKEY(Name)) FROM [Company] WHERE Id = Company.Id),
    Address
  FROM Company;

这给出了相同的错误,因为 Open 不返回任何内容,它是一个 void 语句。

有什么方法可以让 NHibernate 在其他地方调用 Open 吗?也许只是在打开连接之后或在某处的会话处理中?

否则,是否有有效的 SQL 语法让该语句在查询中工作?

视图、函数和存储过程不是一种选择,因为它们违背了加密列的目的。

- - 编辑 - -

打开会话时执行 Open 语句并将其放入配置中:

<property name="Name" column="Name" formula="CONVERT(NVARCHAR(150), DECRYPTBYKEY(Name))" />

似乎解决了一半的问题,该字段是只读的:-(

顺便说一句,使用普通 SQL 更新字段也会产生疯狂的结果。当我这样做时:

UPDATE Company 
  SET Name = ENCRYPTBYKEY(KEY_GUID('MyKey'), 'Hello World')
  WHERE Id=1000;

然后用 回读CONVERT(NVARCHAR(150), DECRYPTBYKEY(Name)),我得到了一些有趣的字符'效汬潗汲d'而不是'Hello World'。

我想升级我们的 SQL2005 数据库并使用Remus Rusanu提到的 TDE 是最好的选择。

4

2 回答 2

3

你加密的目的是什么?通过使用由数据库主密钥加密的证书,看起来就是这样,任何用户或应用程序都可以解密数据。您不提供加密保护,您只提供访问保护(授予/拒绝/撤销对数据和/或密钥的访问)。加密保护将要求您的用户指定解锁密钥层次结构根所需的密码。您正在做的事情具有有效用途(失去媒体保护),但透明数据库加密BitLocker可以更好地处理 100 万倍。

至于您的问题:只需在会话中打开密钥(即当您打开连接时)。尝试在每个语句访问时按需打开它的理由为零。

于 2013-05-28T09:09:54.693 回答
1

对于读取期间的解密,您可以在公式中使用DECRYPTBYKEYAUTOCERT - 执行解密而无需指定 OPEN SYMMETRIC KEY。不幸的是,它是一个公式字段意味着它只能用于读取。这个由 5 部分组成的博客系列详细介绍了如何使这项工作用于读写,但我承认该系列的作者也是如此 - 它有点 hacky。

于 2018-02-27T21:09:29.473 回答