【问题标题】:How to I securely store social security numbers in a database?如何将社会安全号码安全地存储在数据库中?
【发布时间】:2015-11-09 07:12:24
【问题描述】:

我正在开发一个用户需要提交其社会安全号码的网络应用程序。

我想使用非对称密钥进行加密,因此如果 Web 服务器受到威胁,私钥仍然是安全的。该应用程序不会在网络服务器上处理。

但是,应用需要能够知道 SSN 是否与 A 的重复项和 B 的重复,以允许用户返回他们的应用程序。

这个可以吗?

使用类似于密码存储方式的单向哈希是否有意义,否则会损害数据?

因为只有 aprox。 100 亿个 SSN。这会产生任何散列算法吗?容易受到暴力攻击。盐在这里有用吗?如果盐是已知的,它是否仍然容易受到暴力破解?是否可以正确隐藏盐,因为如果有人可以访问数据库,他们也可以访问盐?

【问题讨论】:

标签: mysql public-key-encryption encryption-asymmetric


【解决方案1】:

不要加密您的 SSN,对它们进行哈希处理

听起来您应该散列 SSN,而不是加密它们。两者的区别在于散列是单向的,而加密不是。但是由于您不需要验证数据的价值,只需验证完整性,我肯定会使用散列,因为

  1. 散列比加密更安全,因为散列的 SSN 无法取消散列
  2. 哈希仍然允许您验证数据的完整性并检查数据库中的重复 SSN。

如何散列

如果您使用的是 PHP 5 >= 5.5.0,我会强烈推荐使用 PHP 的 built in password hashing functions。它是为这种情况而经过战斗测试和创造的。它甚至会自动生成自己的安全盐(但您仍然可以选择自己提供)。

请务必仔细阅读有关密码哈希函数的documentation,但下面是一个简短示例(取自文档示例):

<?php
// To create the password hash:
$ssn = password_hash($ssn, PASSWORD_DEFAULT);
// To verify the integrity of what the user is entering
// In this example, $hash is the hashed password generated from password_hash
if (password_verify('rasmuslerdorf', $hash)) {
    echo 'SSN is valid!';
} else {
    echo 'Invalid SSN.';
}
?>

记得检查密码散列函数上的docs,以便正确使用它们:

【讨论】:

  • 我确实需要检索数据的值。所以加密是必要的。
  • 因为只有大约。 100 亿个 SSN,即使使用了盐,也不会花费超过几个小时的时间来暴力破解信息。我错过了什么吗?
  • AFAIK,如果你使用强盐,暴力攻击将不起作用。但同样,这只是据我所知。也许您应该在 StackOverflow 的姊妹网站Information Security Stack Exchange 上发帖?如果你必须使用加密而不是散列,我可以推荐openssl_encryptopenssl_decrypt
  • 非常感谢。
  • “散列的 SSN 不能被取消散列”的说法不正确。一旦删除了无效组合(例如,没有 SSN 以 9 开​​头),允许的 SSN 的范围将少于 9 亿。这不到 30 位的熵;蛮力攻击是非常可行的。
【解决方案2】:

游戏有点晚了,但我采取了双管齐下的方法。

我们将 SSN 分为两部分:

  1. XXX-XX
  2. 3847

SSN 的第一部分使用某种加密算法(河豚?)或您选择的任何加密算法进行加密。

数据库:

--------------------------------------------------------
| ID    |   SSN-A    |   SSN-B    | ......   |         |
--------------------------------------------------------
|   1   | N1maA+HCRj |    3847    |    ...   |         |
|   2   | HCRjHQiEx/ |    7254    |    ...   |         |
--------------------------------------------------------

当记录被导出或转储为 CSV 以供其他实体使用时,您可以将 SSN 的第一部分逐个解密,然后重新组装完整的 SSN。

只要密钥被安全地存储,那么这里就有合理的安全感。这样做的额外好处是 - 虽然您无法进行整个 SSN 搜索,但您至少可以通过使用最后 4 位数字来限制它们。存储 SSN 有一套完整的规定,所以无论您选择哪种方式 - 都要小心。

编辑

将列命名为与 SSN 字段无关的名称可能也是明智之举。

【讨论】:

    猜你喜欢
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多