用于确定性加密的T-SQL / CLR功能

时间:2018-03-29 15:33:24

标签: sql-server tsql encryption sql-server-2016 database-indexes

我有一个包含User Agents Strings表的表,其结构如下:

UserAgentStringID INT
UserAgentStringValue VARBINARY(8000)

[UserAgentStringValue]字段使用对称密钥加密。表格结构的先前版本是:

UserAgentStringID INT
UserAgentStringValue NVARCHAR(4000)
UserAgentStringHASH BINARY(32)

我在[UserAgentStringHASH]列上有索引以优化搜索者。

使用新格式时,这样的索引效率不高,因为ENCRYPTION函数使用InitializationVector以便在每次使用相同输入调用加密函数时生成随机值:

  

初始化向量用于初始化块算法。它   并不是一个秘密,但每次打电话都必须是唯一的   加密功能是为了避免暴露模式。

所以,我可以在我的加密字段上创建索引,但如果我尝试按加密值搜索,我将无法找到任何内容。

我不想使用HASH因为使用哈希函数不是安全技术。如果有人拥有包含所有或大量用户代理的表数据和表,他/她将能够通过哈希执行连接并显示我的数据。

SQL Server 2016 SP标准版中,我们Always Encrypted允许使用Deterministic Encryption作为列值 - 这意味着相等的比较正在运行,并且可以创建索引。

我正在寻找一种通过其他技术优化搜索的方法,或者使用CLR实现确定性加密的方法?

知道没有解决方法也适合我。我想我会用性能来支付数据保护。

1 个答案:

答案 0 :(得分:0)

我正在发布有关此问题的解决方法-这不是理想的解决方案,但是它在速度和安全性之间进行了折衷。

详细信息

  • 列必须加密(让我们说一个电子邮件地址)
  • 必须执行快速搜索(假设电子邮件是用于登录的,我们需要尽快找到记录)
  • 由于各种原因,我们无法使用始终加密的确定性加密
  • 我们不想将hash函数事件与salt一起使用-如果每个用户都拥有salt,则ze ben可能能够使用大型示例数据库读取哈希值

安全层次结构

有多种实现安全性层次结构的方法。 MSDN的以下架构对此进行了很好的描述。

enter image description here

在我们的环境中,我们正在使用数据库材料密钥->证书->对称密钥层次结构。只有DBA know DMK密码可以访问证书和对称密钥。有些开发人员可以使用普通的T-SQL加密/解密数据,而其他开发人员则不能。

请注意,使用始终加密,您可以进行角色分离-使用数据的人员无法访问密钥,而有权访问密钥的人员无法访问数据。对于我们来说,我们想保护我们的数据不受外界的侵害,并拥有其他内部授予/记录数据访问权限的技术。

有权访问加密数据的开发人员

可以访问受保护数据的开发人员可以对其进行加密和解密。他们无权访问对称密钥值。如果可以访问对称密钥值,则ze能够decrypt没有用于保护对称密钥的证书的数据事件。基本上,只有sys.admins和db_owners可以访问对称密钥值。

如何哈希

我们需要一个散列来进行快速搜索,但是我们不能使用未经加密的盐。从安全角度来看,没有盐的哈希就像纯文本。因此,我们决定使用对称键值作为盐。它是这样的:

SELECT @SymmetricKeyValue = CONVERT(VARCHAR(128), DECRYPTBYCERT(C.[certificate_id], KE.[crypt_property]), 1)
FROM [sys].[symmetric_keys] SK
INNER JOIN [sys].[key_encryptions] KE
    ON SK.[symmetric_key_id] = KE.[key_id] 
INNER JOIN [sys].[certificates] C
    ON KE.[thumbprint] = C.[thumbprint]
WHERE SK.[name] = @SymmetricKeyName;

然后将值连接到您的电子邮件地址,然后计算哈希值。这对我们有好处,因为我们将哈希绑定到安全性层次结构。对于每条记录来说,盐并没有什么不同,都是相同的-但是,如果知道对称密钥值,则ze能够直接解密数据。

注意事项

您需要创建例程(存储过程,触发器),这些例程将使用EXECUTE AS OWNER子句通过哈希值或计算哈希进行搜索。否则,开发人员将无法执行它们,因为只有sys.admins和db_owners可以访问对称密钥值。