安全存储和通过社会安全号码进行搜索

13

我正在开发一个网络补充系统,其为人力资源部门所需,用于存储和搜索以前员工的记录。尽管我反对该要求,但最终还是决定该系统必须同时启用通过社会安全号码(SSN)进行搜索和检索完整 SSN 的功能。抛开我的异议不谈,采取一些措施来保护这些数据实际上将大大改善他们目前的做法(你可不想知道)。

我已经做了很多研究,我认为我已经想出了一个合理的计划——但像所有与密码学/安全相关的事情一样,有很多复杂性,而且很容易犯错。我粗略的计划如下:

  1. 在应用程序的首次运行时,使用 RijndaelManaged 生成一个大随机盐和一个 128bit AES 密钥。
  2. 将它们写入一个纯文本文件以备紧急恢复。此文件将离线存储在一个安全的物理位置。应用程序将检查该文件的存在,并在仍然存在时发出警告。
  3. 在某处安全地存储盐和密钥。这部分我没有很好的答案。我计划使用 DPAPI,但我不知道它最终有多安全。我是否应该只将其保留为纯文本并限制文件系统访问到存储它的目录中?
  4. 在将记录写入数据库时,使用上述大盐值对 SSN 进行哈希处理以生成一个可搜索(但不可恢复,除非获得盐并穷举所有可能的 SSN)的字段,并使用新的 IV(存储在旁边)进行 AES 加密原始 SSN 值以生成一个可检索(使用密钥/iv),但不可搜索(因为两次加密同一个 SSN 应产生不同输出)的字段。
  5. 在搜索时,只需对要搜索的值使用相同的盐进行哈希处理并在数据库中查找。
  6. 在检索时,使用 AES 密钥/IV 解密来自数据库的值。

除了需要一种相对安全的方式来存储密钥(上面的第 3 点),这个计划似乎足够牢固。

对我们无效的事情:

  • “不要做这些”不是选项。这需要完成,如果我们不这样做,他们将a)对我们生气并且b)只是通过电子邮件在明文文档中传递所有数字。

这将仅限于我们内部网络,因此至少具有该层保护,无论实现了什么。对应用程序本身的访问将由Active Directory控制。

感谢您的阅读和任何建议。

更新#1: 我从评论中意识到保留社会安全号检索字段的私有IV毫无意义。我更新了计划,以便为每个记录正确生成一个新的IV并将其存储在加密值旁边。

更新#2: 我将硬件内容从我们无法操作的列表中删除。我进行了一些研究,发现这些东西比我想象的更容易获取。使用其中一种USB安全令牌是否为密钥存储增加了有意义的安全性?


1
这个问题不应该去IT安全问吗? - Oded
1
我们肯定不希望他们对你生气。 - Jonesopolis
第一句:http://security.stackexchange.com/ 可能会更有帮助。 第二句:我认为每次加密都生成一个新的IV,并将其与加密的SSN一起存储,这样你就无法判断两个地方的SSN是否相同,会更好。但是请注意,我不是一位安全专家。在实施之前,请彻底研究该选项。 - Mike Precup
1
我喜欢它,但需要注意的是哈希时使用的盐不需要保密。每个SSN的盐独特(就像IV一样)会更好。你甚至可以使用IV作为盐,一举两得。 - Eric Petroelje
如果系统需要支持检索社会安全号码,那么猫已经被放出来了。我不认为加密存储可以增加保护。如果这是一个人力资源应用程序,那么希望它是一个具有数据库和表格安全性的安全应用程序。实际上,他们入侵数据库的机会有多大,但不入侵盐呢? - paparazzo
显示剩余5条评论
4个回答

2

我最近也遇到了类似的问题,决定使用HMAC进行哈希。这将比简单的哈希提供更高的安全性,特别是因为您不能盐值(否则它就无法被搜索)。

然后,像您所说的那样,使用随机盐和AES进行可逆加密。

也许您不需要加密这些数据,但我别无选择,这似乎是一个合理的解决方案。

我的IT安全问题:https://security.stackexchange.com/questions/39017/least-insecure-way-to-encrypt-a-field-in-the-database-so-that-it-can-still-be-in


2
关于密钥存储,如果你选择将AES密钥存储在web.config中,有两种方法可以使用。第一种方法是使用DPAPI,这将为该框中的web.config应用程序设置进行加密。另一种方法是通过RSA密钥(请查看此MSDN教程),这将像DPAPI一样加密您的web.config,但您可以在多个框上使用RSA密钥,所以如果应用程序是集群的,则RSA密钥更好(只是设置更复杂)。
关于在运行应用程序之前在不运行应用程序的机器上生成密钥,这样就没有机会将文本文件留在目录中。应按以下方式生成密钥。
1. 使用RngCryptoServiceProvider生成随机值。 2. 使用RngCryptoServiceProvider生成随机盐值。 3. 使用PBKDF2(Rfc2898DeriveBytes)哈希两个值。
使用密钥派生方法的原因是它保护您,以防RngCryptoServiceProvider因某种原因被发现不安全,这种情况经常发生于随机数生成器。
使用AES 256代替AES 128,原因是这些算法无论如何都非常快,所以获得更高的安全性几乎是免费的。还要确保您正在使用CBC或CTR模式中的算法(CTR可在BouncyCastle库中使用)。
现在,如果有人能够在你的目录中放置aspx文件,则这不会绝对保护您的密钥。因为该文件将成为您的应用程序的一部分,它将可以访问您的解密值,包括您的密钥。我之所以提到这一点,是因为您的网络和服务器安全必须达到最高水平,因此我强烈建议您与网络安全团队紧密合作,确保除需要访问权限的HR部门外,没有人可以访问该框(防火墙而不是Active Directory)。切勿以任何方式公开访问此应用程序。
您也不能相信您的HR部门,有人可能会成为社交工程攻击的受害者,并最终泄露他们的登录信息,从而破坏您的安全模型。因此,除了与网络团队合作外,您还应该集成双因素身份验证机制来进入系统,强烈建议使用实际的RSA密钥或类似物,而不是实施TOTP。这样,即使某个部门的人泄露了密码,因为他们认为他们正在赢得免费的iPad,攻击者仍需要物理设备才能进入应用程序。
记录所有信息,每当有人看到社会安全号码时,请确保将其记录在某个永久记录的位置,并定期进行归档。这样可以让您快速采取措施。我还会限制每个人在特定时间内可以查看多少条记录,这样您就知道是否有人在从应用程序中挖掘数据。
创建一个SQL用户专门访问此表,不要让任何其他用户访问该表。这将确保只有特定的用户ID和密码才能查看表格数据。
在部署到生产环境之前,您应该雇用渗透测试团队来测试应用程序并查看他们能够获取什么信息,这将大大增强应用程序对潜在攻击者的防御能力,他们还可以为您提供优秀的建议以加强应用程序的安全性。

0
为每个记录创建新的盐和IV。如果您需要出于某种原因(希望不包含我的社会安全号码)将数据转储到报告中,则可以使用您描述的具有唯一盐和IV的方法。如果您只需要搜索社会安全号码,则实际上可以对其进行哈希处理,而不是使用可逆加密(更安全)。

3
在谈到社会安全号码(SSN)时,哈希算法是否等同于可逆加密,因为数据中熵值很低呢?如果有人知道如何执行哈希算法(即盐是什么),那么对一百万个可能的 SSN 进行哈希处理并查看哪些与目标匹配将变得轻而易举。 - David Hay
你所描述的是彩虹表——哈希查找。这正是我和其他人提议使用唯一盐值对值进行哈希处理的原因。这使得创建这种类型的表格非常困难。您需要为每个记录生成每个可能的哈希,这需要很长时间。简单地使用通用盐/密钥组合进行加密或哈希处理非常薄弱。 - drz
1
根据我的理解,使用每个记录的唯一盐值难道不会破坏我后来基于社会安全号码进行搜索(匹配)的能力吗?此外,考虑到社会安全号码的性质,您甚至需要彩虹表吗?看起来攻击者可以轻松地为每个记录计算出每个可能的(或合理的,考虑到社会安全号码的限制)哈希值 - 无论是否使用唯一盐。 - David Hay

0

我记得曾经在某个地方读到过,对于有限的输入集进行哈希处理是没有任何意义的。快速搜索后,我发现了这篇类似的 SO 帖子:

Hashing SSNs and other limited-domain information

我必须承认,我也不是安全专家,但考虑到可能的输入数量远小于 10^9,而任何合格的黑客应该能够在几小时内轻松完成,哈希 SSN 似乎只是增加了一层小小的麻烦,而不是实际的安全/难度屏障。

与其这样做,你可以做些其他的事情吗?例如,如果攻击者能够将姓名与数字关联起来(因为任何人都可以轻松枚举出所有数字),那么你可以以一种不可行攻击的方式加密 SSN 所链接的用户 ID 吗?我假设你的员工表中有某种 ID,但也许可以对他们的电子邮件或某种 guid 进行哈希处理?这样,即使他们获得了你的 SSN 数据,他们也无法确定它属于哪个员工,直到他们设法暴力破解该链接。

然而,这种方法也存在缺陷,因为您的公司可能总共没有那么多员工。此时,只需猜测并检查公司目录以获取所有信息即可。无论如何,如果必须将社会安全号码与其他身份识别数据存储在一起,这种安全漏洞都将存在。


是的,我基本上得出结论,黑客可以轻松地反向哈希社会安全号码,只要知道用于哈希的盐值。如果您能够保持盐值的机密性,就可以防止这种情况,但此时您几乎在以一种不好的方式进行实际对称加密。无论如何,整个系统的安全性都取决于保护秘密密钥。 - David Hay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接