我正在开发一个网络补充系统,其为人力资源部门所需,用于存储和搜索以前员工的记录。尽管我反对该要求,但最终还是决定该系统必须同时启用通过社会安全号码(SSN)进行搜索和检索完整 SSN 的功能。抛开我的异议不谈,采取一些措施来保护这些数据实际上将大大改善他们目前的做法(你可不想知道)。
我已经做了很多研究,我认为我已经想出了一个合理的计划——但像所有与密码学/安全相关的事情一样,有很多复杂性,而且很容易犯错。我粗略的计划如下:
- 在应用程序的首次运行时,使用 RijndaelManaged 生成一个大随机盐和一个 128bit AES 密钥。
- 将它们写入一个纯文本文件以备紧急恢复。此文件将离线存储在一个安全的物理位置。应用程序将检查该文件的存在,并在仍然存在时发出警告。
- 在某处安全地存储盐和密钥。这部分我没有很好的答案。我计划使用 DPAPI,但我不知道它最终有多安全。我是否应该只将其保留为纯文本并限制文件系统访问到存储它的目录中?
- 在将记录写入数据库时,使用上述大盐值对 SSN 进行哈希处理以生成一个可搜索(但不可恢复,除非获得盐并穷举所有可能的 SSN)的字段,并使用新的 IV(存储在旁边)进行 AES 加密原始 SSN 值以生成一个可检索(使用密钥/iv),但不可搜索(因为两次加密同一个 SSN 应产生不同输出)的字段。
- 在搜索时,只需对要搜索的值使用相同的盐进行哈希处理并在数据库中查找。
- 在检索时,使用 AES 密钥/IV 解密来自数据库的值。
除了需要一种相对安全的方式来存储密钥(上面的第 3 点),这个计划似乎足够牢固。
对我们无效的事情:
- “不要做这些”不是选项。这需要完成,如果我们不这样做,他们将a)对我们生气并且b)只是通过电子邮件在明文文档中传递所有数字。
这将仅限于我们内部网络,因此至少具有该层保护,无论实现了什么。对应用程序本身的访问将由Active Directory控制。
感谢您的阅读和任何建议。
更新#1: 我从评论中意识到保留社会安全号检索字段的私有IV毫无意义。我更新了计划,以便为每个记录正确生成一个新的IV并将其存储在加密值旁边。
更新#2: 我将硬件内容从我们无法操作的列表中删除。我进行了一些研究,发现这些东西比我想象的更容易获取。使用其中一种USB安全令牌是否为密钥存储增加了有意义的安全性?