我正在开发一个用户需要提交社会安全号码的网络应用程序。
我想使用非对称密钥进行加密,因此如果Web服务器受到威胁,私钥仍然是安全的。该应用程序不会在Web服务器上处理。
但是,应用程序需要能够知道SSN是否与A不重复,不允许重复,而B允许用户返回其应用程序。
可以这样做吗?
使用类似于密码存储方式的单向哈希还是会损害数据?
因为只有aprox。 10亿SSN。这是否会产生任何哈希算法。易受蛮力攻击。盐有帮助吗?如果盐已知不是它仍然易受蛮力?是否可以正确隐藏盐,因为如果有人访问数据库,他们也可以访问盐?
比赛有点晚了,但我采取了双管齐下的方法。
我们将SSN分为两部分:
SSN的第一部分是使用一些加密算法(河豚?)或您选择的任何风格加密的。
数据库:
--------------------------------------------------------
| ID | SSN-A | SSN-B | ...... | |
--------------------------------------------------------
| 1 | N1maA+HCRj | 3847 | ... | |
| 2 | HCRjHQiEx/ | 7254 | ... | |
--------------------------------------------------------
当记录被导出或转储到CSV以供另一个实体使用时,您可以逐个解密SSN的第一部分,然后重新组装完整的SSN。
只要密钥存储安全,那么这里就有一种合理的安全感。这样做的另一个好处是 - 虽然您无法进行整个SSN搜索,但您至少可以使用最后4位数来限制它们。有关存储SSN的一整套规定,无论你选择哪种方式 - 都要小心。
编辑
将列命名为SSN字段的非确定性也可能是明智的。
听起来你应该散列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,以便正确使用它们: