索引sql server中的加密列

时间:2014-10-13 15:50:53

标签: sql-server

我将患者健康信息存储在SQL Server 2012数据库中。当我搜索患者姓名时,他们的姓名是加密的,因此搜索速度非常慢。如何在加密列上添加索引?

我在varbinary字段上使用对称密钥加密(256位AES)。

患者的名字,姓氏,地址,电话号码,DOB,SSN都有单独的加密字段。除SSN外,所有这些都是可搜索的(部分)。

3 个答案:

答案 0 :(得分:4)

以@PhillipH提供的答案为基础:如果您在(比方说)姓氏上执行精确搜索,则可以包含定义为CHECKSUM(encrypt(last_name))的计算列(加密操作encrypt) 。这是安全的,因为它不会泄露任何信息 - 加密值的校验和不会显示有关明文的任何信息。

Create an index on this computed column。要搜索名称,而不是仅仅执行WHERE encrypted_last_name = encrypt(last_name),请在哈希上添加搜索:WHERE encrypted_last_name = encrypt(last_name) AND CHECKSUM(encrypt(last_name)) = hashed_encrypted_last_name。这要快得多,因为SQL Server只需要在索引中搜索一个小整数值,然后验证名称实际上是否匹配,从而减少要检查的数据量。请注意,在此方案中没有数据被解密,无论是否有CHECKSUM - 我们只搜索加密值。加速不是来自减少加密/解密的数据量(只传递您传入的数据),而是需要编制索引并进行相等比较的数据量。

唯一的缺点是,这不允许部分搜索,甚至是案例变异,事实上,安全地做这件事并非易事。大小写相对简单(hash encrypted(TOUPPER(name)),确保使用不同的键来避免相关),但部分匹配需要专门的索引。我能想到的最简单的方法是使用像Lucene这样的单独服务来进行索引,但是让它为其文件使用安全存储(即Windows中的加密文件系统(EFS))。当然,这确实意味着需要认证的单独系统 - 但我想不出任何完全保留在SQL Server中且不需要额外代码的方便解决方案。

如果您仍然可以更改数据库设计/存储,您可能希望考虑透明数据加密(TDE),它具有在引擎级别的SQL Server中的,良好,透明和集成的巨大优势。部分匹配不仅要快得多,因为单个行不需要解密(只是整个页面),如果速度不够快,你可以创建一个也将被加密的全文索引。不过,我不知道TDE是否符合您的安全要求。

答案 1 :(得分:1)

作为一种编程解决方案,如果您不需要部分匹配,则可以在另一个字段中以明文形式存储哈希,并在客户端/应用服务器上使用相同的哈希算法并匹配哈希值。这可能会出现误报,但会否定解密数据的必要性。

答案 2 :(得分:0)

如果您使用的是Microsoft SQL Server隐式cryptobykey函数,则在该列上使用索引没有任何好处,因为由于sql server本身使用随机iv,因此sql sever cryptobykey函数每次对相同的输入都会有不同的输出。