快速搜索加密数据



我需要加密应用程序DB中的个人身份信息(PII)数据。该应用程序在系统中使用智能搜索,使用发音,名称词根和部分词搜索来快速查找名称和地址。

如果我们对这些字段进行加密(在应用层加密的PII数据),搜索将受到记录量的影响,因为我们不能以正常的方式依赖SQL,搜索引擎(在应用程序中)将切换到读取所有值,解密并进行搜索。

有什么简单的方法来解决这个问题,这样我们就可以总是加密PII数据,并为我们的用户群提供快速搜索功能?

我们使用PHP Web/App Tier (Zend Server和SQL Server DB)。该应用程序目前没有使用Lucene等技术。

感谢

Cheers

加密数据也使它看起来非常像随机的位字符串。这就排除了通过索引进行快捷搜索的任何操作。

对于某些加密数据,例如社会保险号,您可以在单独的列中存储该号码的哈希值,然后对该哈希字段建立索引并搜索该哈希值。显然,这个功能有限,并且在搜索名称如"ROB%"

中没有价值。如果您的数据库得到了适当的保护,这听起来不错,但如果坏人可以闯入并窃取您的服务器或备份,则很难实现。如果它确实是一种要求(而不仅仅是一种可协商的营销驱动项目),你就被迫遵守。

您可以协商将部分数据以未加密的方式存储,例如,姓氏的前3个字符或诸如此类,以便您仍然可以使用有用的(如果不是完美的)索引。

添加

我应该补充说,您可能被允许对名称字段的一部分进行哈希,并在该哈希上进行搜索——假设您不被允许存储未加密的部分名称——您再次失去了用处,但它可能仍然比没有索引要好。

为了使这种散列有用,它不能是种子的——也就是说,所有记录必须基于相同的种子(或没有种子)进行散列,否则您将无法执行表扫描。

您还可以创建一个覆盖索引,当然仍然是加密的,但是由于减少了I/O,表扫描可能会更快;内存要求。

我将试着写下这一点,因为加密社区通常很难理解(我忍住了在这里插入双关语的冲动)。

我使用的一个特定的解决方案是为您希望索引和快速搜索的东西(如姓氏)创建索引表,然后只加密这些索引列。

例如,您可以创建一个表,其中键列包含3个字母字符串中字符a - z的每种可能组合的一个条目(除了第一个字符之外的所有字符都包含空格)。这样的:

A__
AA_
AAA
AAB
AAC
AAD
..
..
..
ZZY
ZZZ

当你添加一个人到你的数据库时,你将他们的索引添加到第二列,这只是一个人ID的列表。

示例:在patients表中,smith的条目如下:

231    Smith    John    A     1/1/2016   .... etc

和这个条目将被加密,可能除了ID 231之外的所有列。然后将此人添加到索引表中:

SMH    [342, 2342, 562, 12]
SMI    [123, 175, 11, 231]

现在加密第二列(ID列表)。因此,当你搜索一个姓氏时,你可以输入"smi",并迅速检索到所有以这个字母组合开头的姓氏。如果你没有密钥,你只会看到一个密文。实际上,您可以在这样的表中创建两列,一列用于名,一列用于姓。

此方法与明文索引一样快,并且使用了一些相同的基本原则。您可以对soundex ('sounds like')做同样的事情,方法是构造一个表,将所有可能的soundex模式作为左列,并将person (patient?)Id是另一列。通过创建多个这样的索引,您可以开发一种很好的方法来研究您正在寻找的名称。

如果你愿意,你也可以扩展到更多的字符,但显然这会使你的表每一个字母都延长一个数量级以上。它确实具有使索引更具体的优点(并不总是您想要的)。说实话,任何类型的直方图,你可以用他们的名字来分类他们。我也见过这样写出生日期的。任何你需要搜索的

这样的表存在一些漏洞,特别是因为某些bucket的条目数量可能非常短,攻击者可能会确定哪些名称在系统中没有条目。然而,在索引列表中使用一种随机的"盐"可以帮助解决这个问题。其他问题包括每次值更新时需要不断更新所有索引。

但即便如此,这种方法创建了一个很好的加密系统,超越了静态数据。静态数据仅保护您免受无法获得系统授权的攻击者的攻击,但是该系统为DBA和其他可能需要在数据库中工作但不需要(或不希望)查看其中包含的个人数据的人员提供了一层保护。他们只会看到密文。因此,实际需要/想要访问此信息的用户或系统需要一个额外的密钥。Ashley Madison采用这样的策略是明智的。

希望这对你有帮助。

有时候,"加密数据"实际上意味着"加密静态数据"。也就是说,您可以使用透明数据加密来保护数据库文件、备份等,但是可以通过查询直接查看数据。找出这是否足以满足你想要满足的任何规定,这将使你的工作更容易。

最新更新