WHERE子句中的SQL加密列

时间:2010-08-24 20:21:56

标签: sql-server sql-server-2008 encryption-symmetric aes

我希望使用对称密钥来应用SQL列级加密。创建数据库主密钥,证书和对称密钥所需的初始步骤似乎很简单,我已成功使用对称密钥测试加密/解密数据。

但是,一旦数据被加密,我不知道如何最好地查询它。 E.g。

SELECT PlainTextA, PlainTextB, PlainTextC 
WHERE CONVERT(varchar, DECRYPTBYKEY(EncyptedColumn)) = @SearchTerm

肯定会导致全表扫描?

我认为可能有用的其他选项是首先加密搜索条件,例如

SELECT PlainTextA, PlainTextB, PlainTextC 
WHERE EncyptedColumn = ENCRYPTBYKEY(KEY_GUID('KeyName'), @SearchTerm)

但这不起作用,因为生成的加密值总是不同。

任何建议都将不胜感激。

3 个答案:

答案 0 :(得分:14)

典型的方法是将加密值都存储为值的单向散列。当您寻找特定值时,您将寻求哈希值。通过这种方式,您可以高效查询,无需解密每个行,以便找到您感兴趣的值:

create table Table (
EncryptedColumn varbinary(max),
HashValue binary(20),
PlainA int,
PlainB varchar(256),
PlainC Datetime);

create index ndxTableHash on Table(HashValue);

select PlainA, plainB, PlainC
from table
where HashValue = HashBytes('SHA1', @searchTerm);

从理论上讲,你可以在蓝色的月亮中发生一次哈希冲突,对于在解密的列上添加双重检查是偏执的安全:

select PlainA, plainB, PlainC
from table
where HashValue = HashBytes('SHA1', @searchTerm)
and DecryptByKey(..., EncryptedColumn) = @searchTerm;

另见Indexing encrypted dataSQL Server 2005: searching encrypted data

答案 1 :(得分:2)

您有一个选项是向表中添加一个新列(或者在其中包含计算列的WITH SCHEMABINDING视图,并使用搜索值的单向HASH进行索引)。它不一定是强大的哈希 - something as simple as CHECKSUM will work。然后,在查找中对搜索值进行哈希处理,并通过索引对其进行过滤。这样,您可以暴露可搜索和可索引的内容,而不会实际暴露值本身。

但是,如果有另一种方法直接这样做,我很想知道它是什么:)

答案 2 :(得分:-2)

另一种选择是使用包含一列解密值的View,并根据它查找记录。

SELECT PlainTextA, PlainTextB, PlainTextC from TheView 
WHERE DecryptedColumn = @SearchTerm