How to I securely store social security numbers in a database?

左心房为你撑大大i 提交于 2019-12-08 10:19:55

问题


I'm working on a web application which the users will need to submit their social security numbers.

I would like to use asymmetric keys for encryption so if the web server is compromised the private key will still be safe. The application won't be processed on the webserver.

However the app needs the ability to know if the SSN is a duplicate to A not allow duplicates and B to allow users to come back to their application.

Can this be done?

Does it make sense to use a one way hash similar to the way passwords are stored or will that compromise the data?

Since there are only aprox. 10 Billion SSNs. Does that make any hashing alg. susceptible to brute force attacks. Will a salt help here? If the salt is known isn't it still susceptible to brute force? Is it possible to properly hide a salt since if someone has access to the database they also have access to the salt?


回答1:


A little late to the game, but I took a two-pronged approach.

We split the SSN into two parts:

  1. XXX-XX
  2. 3847

The first part of the SSN is encrypted using some encryption algorithm (blowfish?) or whatever flavor you choose.

The database:

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

When records are exported or dumped into a CSV for consumption by another entity, you can decrypt the first part of the SSN one by one and then reassemble the complete SSN.

As long as the key is stored securely, then there is a reasonable sense of security here. The added benefit of this is - while you cannot do a whole SSN search, you can at least limit them by using the last 4 digits. There is a whole set of regulations around storing SSN's, so whatever way you choose - be careful.

Edit

It would also probably be wise to name the columns something non deterministic of an SSN field.




回答2:


Don't encrypt your SSNs, hash them

It sounds like you should be hashing the SSNs rather than encrypting them. The difference between the two is that hashing is one-way while encryption is not. But as you don't need to verify the value of the data, just the integrity, I would definitely use hashing because

  1. Hashing is more secure than encryption as hashed SSNs can not be unhashed
  2. Hashing still allows you to verify the integrity of the data and check for duplicate SSNs in your database.

How to hash

If you're using PHP 5 >= 5.5.0, I would strongly recommend using PHP's built in password hashing functions. It's battle tested and created for this very situation. It even auto generates its own secure salt (but still has the option of you providing your own).

Make sure you carefully read the documentation on password hashing functions, but a short example (taken from the docs' example) is below:

<?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.';
}
?>

Remember to check the docs on the password hashing functions so you correctly use them:

  • password_get_info
  • password_hash
  • password_needs_rehash
  • password_verify


来源:https://stackoverflow.com/questions/32037007/how-to-i-securely-store-social-security-numbers-in-a-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!