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

C# 通过社会安全号码安全地存储和搜索,c#,asp.net,.net,encryption,sensitive-data,C#,Asp.net,.net,Encryption,Sensitive Data,因此,我正在开发一个补充的基于网络的系统,该系统由人力资源部负责存储和搜索前员工的记录。我反对这一要求,但最终,该系统必须能够通过完整SSN进行搜索,并检索完整SSN。抛开我的声明不谈,采取一些措施来保护这些数据实际上比他们现在正在做的事情有了巨大的改进(你不想知道) 我已经做了很多研究,我认为我已经提出了一个合理的计划——但就像所有与加密/安全相关的事情一样,它非常复杂,而且很容易出错。我的大致计划如下: 在应用程序第一次运行时,使用RijndaelManaged生成一个大的随机salt和一个

因此,我正在开发一个补充的基于网络的系统,该系统由人力资源部负责存储和搜索前员工的记录。我反对这一要求,但最终,该系统必须能够通过完整SSN进行搜索,并检索完整SSN。抛开我的声明不谈,采取一些措施来保护这些数据实际上比他们现在正在做的事情有了巨大的改进(你不想知道)

我已经做了很多研究,我认为我已经提出了一个合理的计划——但就像所有与加密/安全相关的事情一样,它非常复杂,而且很容易出错。我的大致计划如下:

  • 在应用程序第一次运行时,使用RijndaelManaged生成一个大的随机salt和一个128位AES密钥
  • 将这两个文件写入明文文件,以便紧急恢复。此文件将脱机存储在安全物理位置。应用程序将检查文件是否存在,如果文件仍然存在,则发出尖叫警告
  • 把盐和钥匙安全地存放在某个地方。这是我没有很好答案的部分。我曾计划使用DPAPI——但我不知道最终它到底有多安全。我是否应该将其保留为纯文本,并限制文件系统对其存储目录的访问
  • 将记录写入数据库时,将SSN与上面的大salt值一起散列,以生成可搜索的字段(但在未获得salt和brute强制所有可能的SSN的情况下无法恢复),AES使用新的IV(存储在旁边)加密原始SSN值,以生成可检索的字段(使用密钥/IV)但不可搜索(因为对同一SSN加密两次会产生不同的输出)
  • 搜索时,只需使用相同的salt散列搜索值,然后在数据库中查找它
  • 检索时,使用AES密钥/iv从数据库解密该值
  • 除了需要一种以相对安全的方式存储密钥(上面的数字3)之外,它似乎足够可靠

    对我们不起作用的事情:

    • “不要这样做”不是一个选项。这需要完成,如果我们不这样做,他们会a)对我们生气,b)通过电子邮件在明文文档中传递所有数字
    这将只是我们网络的内部,所以我们至少在这里实现的任何东西之上有一层保护。对应用程序本身的访问将由active directory控制

    感谢您的阅读和任何建议

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

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

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

    我想我曾在某个地方读到过,对有限的输入集进行散列处理,结果一无所获。谷歌很快发现了这篇文章,并发出了类似的警告:

    我必须承认,我也不是安全专家,但考虑到可能的输入数量远小于10^9,任何一个体面的黑客都应该能够在几个小时内轻松通过,对SSN进行哈希处理似乎是在增加一小层麻烦,而不是实际的安全/困难屏障

    与其这样做,你还能做点别的吗?例如,SSN只有在能够将一个名称与一个数字相关联时才对攻击者有价值(因为任何人都可以很容易地枚举出所有数字)。在这种情况下,您能否加密SSN链接到的用户id,使其无法进行攻击?我假设您的employees表有某种ID,但也许可以在他们的电子邮件或某种guid上做一个哈希来代替它?这样,即使他们确实获得了您的SSN数据,他们也无法知道这是哪位员工的,直到他们设法强行使用该链接


    同样,这种方法也是有缺陷的,因为你的公司可能没有那么多的员工。在这一点上,猜测并对照公司目录进行检查将是一个相对简单的事情,以获得所有信息。无论您如何分割它,如果SSN必须与其他标识数据一起存储,则此安全漏洞将存在。

    我最近不得不解决一个类似的问题,并决定使用HMAC进行哈希。这将比简单的散列提供更多的安全性,尤其是当您不能对值进行加密时(否则它将无法搜索)

    然后,正如您所说,使用AES和随机盐进行可逆加密

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


    我的IT安全问题

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

    就生成t而言