13

所以我正在开发一个人力资源部门需要的基于网络的补充系统来存储和搜索前员工的记录。我反对这个要求,但最终它被传下来,系统必须同时启用完整 SSN 搜索和完整 SSN 检索。抛开我的抗议不谈,采取一些措施来保护这些数据实际上将比他们现在用它做的事情有很大的改进(你不想知道)。

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

  1. 在应用程序第一次运行时,使用 RijndaelManaged 生成一个大的随机盐和一个 128 位 AES 密钥
  2. 将这两个都写到明文文件中以进行紧急恢复。此文件将离线存储在安全的物理位置。该应用程序将检查文件是否存在,如果它仍然存在,则会发出警告。
  3. 将盐和钥匙安全地存放在某处。这是我没有很好答案的部分。我正计划使用 DPAPI——但我不知道它到底有多安全。将其保留为纯文本并限制文件系统访问其存储的目录会更好吗?
  4. 将记录写入数据库时​​,将 SSN 与上面的大盐值散列以生成可搜索的字段(但在没有获得盐和暴力破解所有可能的 SSN 的情况下无法恢复),并且 AES 使用 a 加密原始 SSN 值new IV(存储在旁边)以生成可检索(使用密钥/iv)但不可搜索的字段(因为两次加密相同的 SSN 会产生不同的输出)。
  5. 搜索时,只需用相同的盐对搜索值进行哈希处理,然后在数据库中查找
  6. 检索时,使用 AES 密钥/iv 从数据库中解密值

除了需要一种以相对安全的方式存储密钥的方法(上面的第 3 点)之外,它似乎足够可靠。

对我们不起作用的事情:

  • “不要这样做”不是一个选项。这需要完成,如果我们不这样做,他们会 a) 生我们的气,b) 只需通过电子邮件将所有数字传递到纯文本文档中。

这将仅在我们的网络内部,因此我们至少在此处实施的任何内容之上都有这一层保护。并且对应用程序本身的访问将由活动目录控制。

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

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

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

4

4 回答 4

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)。请勿以任何形式或形式从互联网公开访问此应用程序。

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

记录一切,任何时候有人看到 SSN,请确保将其记录在某个地方,该记录将成为定期存档的永久记录的一部分。这将允许您快速缓解。我还会限制一个人在特定时间范围内可以看到多少记录,这样你就知道是否有人从你的应用程序中挖掘数据。

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

在部署到生产环境之前,您应该聘请渗透测试团队来测试应用程序,看看他们能得到什么,这将大大有助于加强应用程序免受潜在攻击者的攻击,他们可以就如何加强应用程序的安全性。

于 2013-07-19T10:03:01.263 回答
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 -在

于 2013-07-18T22:47:49.123 回答
0

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

于 2013-07-18T20:29:16.143 回答
0

我想我曾经在某处读到过,对一组有限的输入进行散列处理绝对不会让你一无所获。一个快速的谷歌出现了这个 SO 帖子,并带有类似的警告:

散列 SSN 和其他有限域信息

我必须承认我也不是安全专家,但考虑到可能的输入数量远小于 10^9,任何体面的黑客都应该能够在几个小时内轻而易举地通过,散列 SSN 似乎你正在添加一小层烦恼,而不是实际的安全/困难障碍。

除了这样做,你能做点别的吗?例如,只有当 SSN 能够将名称与数字相关联时,SSN 才对攻击者有价值(因为任何人都可以很容易地枚举出所有数字)。在这种情况下,您能否以不切实际的攻击方式加密 SSN 链接到的用户 ID?我假设您的员工表有某种 ID,但也许不是在他们的电子邮件或某种 guid 上做一个哈希?这样,即使他们确实获得了您的 SSN 数据,他们也无法分辨出是哪个员工,直到他们设法暴力破解该链接。

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

于 2013-07-18T20:54:46.053 回答