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

时间:2013-07-18 20:06:50

标签: c# asp.net .net encryption sensitive-data

因此,我正在研究人力资源部门所需的基于网络的补充系统,以存储和搜索前人员的记录。我满足了这个要求,但最终传下来的是系统必须能够通过完整的SSN进行搜索,并检索完整的SSN。除了我的抗议,采取一些步骤来保护这些数据实际上将是他们现在正在做的事情的巨大改进(你不想知道)。

我一直在做很多研究,我认为我已经提出了一个合理的计划 - 但是就像所有加密/安全相关的东西都有很多复杂性,并且很容易犯错误。我的粗略计划如下:

  1. 首次运行应用程序时,使用RijndaelManaged生成大型随机盐和128位AES密钥
  2. 将这两者写入明文文件以进行紧急恢复。该文件将在离线存储在安全的物理位置。应用程序将检查文件是否存在,如果它仍然存在,则尖叫警告。
  3. 将盐和密钥存放在某处。这是我没有很好答案的部分。我打算使用DPAPI - 但我不知道它在一天结束时到底有多安全。我是不是更好的将它留在明文并限制文件系统访问它存储在的目录?
  4. 在向数据库写入记录时,将SSN与上面的大盐值一起散列,以生成可搜索的字段(但不能在不获取盐和暴力的情况下恢复所有可能的SSN),并且AES加密原始SSN值与新的IV(存储在一起)生成一个可检索的字段(使用键/ iv)但不可搜索(因为加密相同的SSN两次应产生不同的输出)。
  5. 搜索时,只需使用相同的哈希搜索值,然后在数据库中查找
  6. 检索时,使用AES密钥/ iv
  7. 解密数据库中的值

    除了需要以相对安全的方式存储密钥(上面的数字3)之外,它似乎足够坚固。

    对我们不起作用的事情:

    • “不要做任何这个”不是一个选择。这需要做,如果我们不这样做,他们会a)对我们生气,b)只是通过电子邮件传递明文档中的所有数字。

    这只是我们网络的内部,所以我们至少在这里实现的任何内容上都有这层保护。对应用程序本身的访问将由活动目录控制。

    感谢您阅读,以及任何建议。

    更新#1: 我从评论中意识到,为SSN检索字段保留私有IV是没有意义的。我更新了计划,为每条记录正确生成新的IV,并将其与加密值一起存储。

    更新#2: 我正在从我不能做的事情列表中删除硬件内容。我做了一些研究,看起来这些东西比我想象的更容易接近。使用其中一个USB安全令牌的东西是否为密钥存储增加了有意义的安全性?

4 个答案:

答案 0 :(得分:2)

关于密钥存储,如果您选择将AES密钥存储在web.config中,则可以使用两种方法。第一种方法是使用你提到的DPAPI。这将加密该框的web.config应用程序设置。您可以使用的另一种方法是通过RSA密钥(查看此MSDN tutorial),这将像DPAPI一样加密您的web.config但是您可以在多个框上使用RSA密钥,因此如果应用程序是群集的那么RSA键更好(设置起来更复杂)。

就运行应用程序之前生成密钥而不是运行应用程序的计算机而言,这样就不可能将文本文件保留在目录中。您应该按如下方式生成密钥。

  1. 使用RngCryptoServiceProvider
  2. 生成随机值
  3. 使用RngCryptoServiceProvider
  4. 生成随机盐值
  5. 使用PBKDF2(Rfc2898DeriveBytes
  6. 散列这两个值

    使用密钥派生方法的原因是,如果发现RngCryptoServiceProvider因随机数生成器发生的某些原因而不安全,它会保护您。

    使用AES 256而不是AES 128,原因是这些算法无论如何都非常快,因此获得更高的安全性几乎是免费的。另外,请确保您在CBC或CTR模式下使用该算法(BouncyCastle库中提供了CTR)。

    如果有人能够在您的目录中放置一个aspx文件,现在这不会给您的密钥绝对保护。由于该文件将成为您的应用程序的一部分,因此它可以访问您的解密值,包括您的密钥。我提到这一点的原因是你的网络和服务器安全性必须是一流的,所以我强烈建议你与你的网络安全团队携手合作,以确保没有人能够访问那个盒子,除了派对之外需要访问的HR部门(防火墙不是Active目录)。不要以任何形式或形式从互联网公开访问此应用程序。

    您也无法信任您的人力资源部门,有人可能会成为社会工程攻击的受害者并最终泄露他们的登录信息,从而破坏您的安全模型。因此,除了与您的网络团队合作之外,您还应该集成双因素身份验证机制以进入系统,强烈建议使用实际的RSA密钥或类似的东西而不是实现TOTP。这样,即使部门的某人因为认为他们赢得了免费的ipad而放弃了密码,攻击者仍然需要一台物理设备才能进入应用程序。

    记录所有内容,每当有人看到SSN时,请务必将其记录在某个位置,该记录将成为定期存档的永久记录的一部分。这样可以让您快速缓解。我还会限制一个人在特定时间范围内可以看到多少条记录,这样您就知道是否有人从您的应用程序中挖掘数据。

    专门创建一个SQL用户来访问该表,不要让任何其他用户有权访问该表。这将确保只有特定的用户ID和密码才能查看表数据。

    在部署到生产环境之前,您应该聘请一个渗透测试团队来测试应用程序,看看他们能够获得什么,这将大大加强潜在攻击者的应用程序,他们可以就如何提供很好的建议加强应用程序的安全性。

答案 1 :(得分:1)

我最近必须解决类似的问题,并决定使用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 :(得分:0)

为每条记录创建一个新的salt和IV。如果由于某种原因需要将数据转储到报告中(希望没有我的SSN),您将能够使用您使用唯一salt和IV描述的方法。如果您只需要搜索SSN,您实际上可以哈希它而不是使用可逆加密(更安全)。

答案 3 :(得分:0)

我想我曾经读过一些有限的输入信息让你一无所获。一个快速的谷歌出现了这个SO帖子类似的警告:

Hashing SSNs and other limited-domain information

我必须承认我也不是安全专家,但考虑到可能的输入数量远小于10 ^ 9,任何体面的黑客都应该能够在几个小时内轻松完成,哈希SSN看起来像你正在增加一小块烦恼,而不是一个实际的安全/难度障碍。

不是这样做,你可以做别的吗?例如,如果SSN只能将名称与数字相关联,那么SSN只对攻击者有价值(因为任何人都可以轻松地枚举所有数字)。在这种情况下,您是否可以加密SSN链接到的用户ID,这种方式对攻击是不切实际的?我假设你的员工表有某种ID,但是可能不是那样在他们的电子邮件或某种guid上做哈希?这样,即使他们确实获得了您的SSN数据,他们也无法告诉哪个员工,直到他们设法蛮力链接。

然而,这种方法也存在缺陷,因为您的公司可能没有那么多员工。那时,猜测和检查公司目录以获得一切都是相对简单的事情。无论你如何分割它,如果SSN必须与其他识别数据一起存储,这个安全漏洞就会存在。