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

2

10

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?

Weems answered 16/8, 2015 at 15:47 Comment(2)
this is a good readTirewoman
maybe interesting? related to storing and retrieving the SSN safely? Cracking_the_Confusion-_Datacenter_Encryption, Also, The Open Web Application Security Project (OWASP) is focused on improving the security of software.Blight
J
4

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.

Joacima answered 9/10, 2017 at 18:24 Comment(0)
E
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:

Extemporize answered 16/8, 2015 at 17:42 Comment(7)
I do need to retrieve the value of the data. So encryption is necessary.Weems
Since there are only approx. 10 billion SSNs it shouldn't take more than a few hours to brute force the information even if salt is used. Am I missing something.Weems
AFAIK, if you use a strong salt, a brute force attack will not work. But again, that is only as far as I know. Perhaps you should post on StackOverflow's sister site, Information Security Stack Exchange? If you must use encryption and not hashing, I can recommend openssl_encrypt and openssl_decrypt.Extemporize
Thanks you very much.Weems
The statement that "a hashed SSN cannot be unhashed" is incorrect. The universe of allowable SSNs are fewer than 900 million once invalid combinations are removed (e.g., no SSN begins with 9). This is less than 30 bits of entropy; a brute force attack is very feasible.Calculus
(See also ErikE's excellent answer to this question, under the header The Insecurity of an SSN Hash)Calculus
MD5ed SSNs can be unhashed; SHA2 will soon follow. "Hashing is one-way" is a phrase that should be removed from the software engineer's lexicon, because it has not been proven that for every function f(x) = x there does not exist an inverse function g(f(x)) which also equals x. God does not play dice.One can say the current hashing algorithms have yet undiscovered solutions and are inefficient to brute force; but one cannot say any hashing algorithm is one-way. The bit-shifting of hashing algorithms create "butterfly patterns" which can be cracked (like folding paper with ink, then unfolding).Custommade

© 2022 - 2024 — McMap. All rights reserved.