My question is very similar to this one, but in my situation I do not need to recover the real value. My concern with just hashing the value is that since there's a finite and (relatively) small number of SSNs possible is that it would be too easy to brute force SSNs.
The SSN will really just be used as a lookup value for multiple records. My idea is to have the application server hash the plaintext SSN using a slow algorithm like PBKDF2 with a static salt. The application server sends this data to the crypto server, which encrypts the data with AES-256 in CBC mode with a static IV. The encrypted data is then hashed with SHA-256, and this is inserted into the database as a hex string.
Here's a flow diagram:
I believe this to be a very secure model since the attacker would need to brute force:
- The encrypted data (256 bits minimum!)
- The IV (128 bits minimum. This can be arbitrarily large so long as its length is a multiple of the block size (16))
- The key (another 256 bits)
- The SSN salt (can be arbitrarily large)
- The SSN (1000000000 options – very fast to compute but with a slow hashing algorithm it'll take a while to get all of them)
As somewhat of an aside, my coworker has two concerns of his own:
- He wants to ensure that there are no duplicate ciphertexts in the DB
- Searches. He had looked at some papers which described searchable symmetric encryption (link 1, link 2, link 3).
My response to #1 is that this would require being able to recover the plaintext SSN, which an attacker would also be able to do.
And for #2, I am not a cryptographer but my reasoning for shutting down this ideas is that I for one do not know of any implemented and thoroughly tested algorithms/libraries supporting this, and these enable "keyword" search. Depending on how that works, the keyword in this context would be the SSN and I really cannot see how it would complicate things with querying the database.
This is a fairly loaded question, but is my model secure and are my points accurate?