如何在数据库中安全地存储社会安全号码?

问题描述 投票:0回答:2

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

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

但是,应用程序需要能够知道SSN是否与A不重复,不允许重复,而B允许用户返回其应用程序。

可以这样做吗?

使用类似于密码存储方式的单向哈希还是会损害数据?

因为只有aprox。 10亿SSN。这是否会产生任何哈希算法。易受蛮力攻击。盐有帮助吗?如果盐已知不是它仍然易受蛮力?是否可以正确隐藏盐,因为如果有人访问数据库,他们也可以访问盐?

mysql public-key-encryption encryption-asymmetric
2个回答
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字段的非确定性也可能是明智的。


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,以便正确使用它们:

© www.soinside.com 2019 - 2024. All rights reserved.