问题
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:
- XXX-XX
- 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
- Hashing is more secure than encryption as hashed SSNs can not be unhashed
- 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