I'm developing an online application that needs the user's social security number.
The application won't be processed on the web server so I'll be using an asymmetric key. So a compromised web server shouldn't compromise the data.
Do I need to append random data since if an attacker gets into the web server he probably also can get the public key and brute force a match between the user and the SSN by trying to encrypt all SSNs?
Does that make sense and is that enough?
We want the user to be able to continue an application using the SSN to continue and also we would like to make sure there are no duplicate SSNs used.
Hence the web server needs to at least be able to determine that the SSN matches without actually knowing the SSN. So we can store a hash in another column similar to the way passwords are used. Is there a better way?
How can I protect against brute force? SSN only have about 10B possible values. That won't take very long. Is there a way to slow down a brute force attack? It can take up to a few seconds as long as a brute force becomes impractical.
Searching online brings up PBKDF2 and Bcrypt as a possible solution. Does that make sense? Will that slow down a brute force attack? Are there any other suggestions?
I want to make sure I'm not missing something that will leave us vulnerable. I realize there is no such thing as 100% secure, I just want to implement the best that's available and know the level of risk.
-- Edit To clarify as requested by Neil Smithline
Its necessary to decrypt the data. However decryption will not happen on the web server. Decryption will take place on a different server therefore I plan on using asymmetric keys for an extra security measure. So the data should not be decryptable from the web server only encrypted.
We need to be able to lookup the data on the web server to know if it already exists without decryting the data.
A. You can't use the public key to match the incoming social. Since there are a very limited amount of SSNs, approx 10B. So we will append random data to secure against a brute force attack. I would like to secure against the attacker compromising the web server and accessing the public key.
B. You can't use a simple hash same reason as A, brute force.
Instead I was thinking of potentially using PBKDF2 or Bcrypt to slow down a brute force.
Does that make sense? Any other suggestions.
As Neil explained below using a hash and salt to lookup duplicates is not practical as it would require checking the entire column.
So we will remove the requirement of not having duplicates.
What still remains is, what can we do to enable the user to continue an application using their SSN without the ability to decrypt the SSN and without becoming vulnerable to brute force?
Does BCrypt sufice? Any other suggestions?
I can always get around this problem by having the users signup and create a username and password first. However I'd rather avoid that if I can. As it creates adds steps for the user.
Can this accomplished without compromising their SSN?