I am developing a solution where each user is identified with a social security number (SSN). So they log in with their SSN and a password.

I would like to encrypt the SSN somehow (client-side) before sending it to the back-end so that anyone with access to the back-end and database cannot know what the SSNs are.

So, I guess a naive approach would be to hash the SSN before sending it over, and the back-end can find the matching row.

Creating a rainbow table for all possible SSNs would not be that big of a challenge, and I guess the whole thing could be cracked in a couple of days, if not less.

Using symmetric or asymmetric encryption yields the same flaw, as the attacker could easily know the password or public key that must be transmitted to the client.

Are there any clever solutions to this kind of problem? I guess whatever the client sends to the server, it must have a random component to it. So how can the server look it up then?

  • $\begingroup$ Do you actually need to know the SSN for any specific purpose other than login, or is it just what you're using as a username? $\endgroup$
    – Ella Rose
    May 10, 2018 at 22:59
  • $\begingroup$ @EllaRose Yes, I need it later on. But I have a separate field where the SSN is symmetrically encrypted, and only the client knows the password to it. The client will send that password to the back-end to verify the person's identity. $\endgroup$
    – HelloWorld
    May 10, 2018 at 23:08
  • $\begingroup$ You might want to include that in your question and/or modify anyone with access to the back-end and database cannot know what the SSNs are., as I interpreted it to mean that even the legitimate provider of the service should not know what the SSNs are. $\endgroup$
    – Ella Rose
    May 10, 2018 at 23:10
  • $\begingroup$ @EllaRose That is indeed correct. I specifically meant both the back-end and database. $\endgroup$
    – HelloWorld
    May 10, 2018 at 23:11
  • $\begingroup$ "encrypt" "hash" "symmetric or asymmetric encryption". Don't use the SSN as the username. Derive at least 2 keys using argon2i(salt = H(service.org | username), passphrase), first a key to symmetrically encrypt the SSN (not hash, so you can decrypt it when needed). The second key is used as a lookup key to push the ciphertext into a store and to later fetch it after logging in. Are you sure that you need the SSN at all? $\endgroup$
    – cypherfox
    May 11, 2018 at 2:28

2 Answers 2


I want to say don't use SSNs like usernames for practical and ethical reasons. Yet I hope that if you switch to normal username/passwords you won't remove the (weak) password protection on encrypted SSNs that you already have. There also may be legal requirements surround SSN storage, but I know nothing about that. Definitely don't use SSNs because you believe in inflicting some "real name" philosophy on users. If you're doing something like filling out forms for a person then consider only storing the SSN client side even if it means they have to type it in multiple times.

If you really must do something like what you describe and can't add a username then store the hash of the pair (SSN, password). To check if a person's password is correct check for set membership of $H(SSN, Password)$ in a hash table*. No need to store (H(SSN), H(password)) like something you might be thinking. You then can replace the SSN ciphertext with the SSN+Password hash. This has the downside that you don't have a pure software way to prevent multiple sign ups. Which may not be a problem if sign up involves paper forms and manual account activation.

I can't think of a way to use salt if you're using SSNS like a username that has to be secret. Normally you use non-secret information to look up salts. You have similar problems as you would have if you used only a password in place of a username+password combo. (Perhaps minus password collision problems). Adding username or email would let you add salt.

You will want to consider where you allow yourself to use the SSN. Client side only? In RAM only? RAM and hard drive? RAM and SSD? Can the SSN end up getting written to swap space? Is hibernate disabled? Will crash dumps contain secrets? Logs?

(Unfortunately I don't know that real world companies really put any thought into these questions.)

Also consider: A person's assigned SSN can be changed. The person assigned to one SSN can change.

* Try to be aware of implementation details. Databases may leak some information. Deleted rows might not actually result in data getting cleared for example. There could be forensicly interesting information in the disk representation of a database as well. (As opposed to history independent data structures.)


Do not use the SSN as a username!!

Like FutureSecurity I cannot speak for the legal liabilities and respective requirements for handling SSNs. The following advice is general and may or may not apply to legal storage of an SSN.

If your server doesn't need to know, then it doesn't need to store the [encrypted] SSN.

To login you should be using client-side memory-hard key derivation function with a deterministic salt and a user chosen passphrase (maybe with a random passphrase generator at registration).

If the user has Javascript disabled, use a <noscript> disclaimer to request that Javascript be enabled and if it is not, the user's password will be sent to the server and a weaker HTTP cookie will be used instead and will expire after N seconds of inactivity.

$$k = \operatorname{kdf}(\text{salt} = \text{service_unique_identifier} \mathop{\|} \text{username}, \text{passphrase})$$

Use $k$ to derive any number of secrets in the client's "trusted" browser $\operatorname{kdf}_k(\text{"purpose"})$.

If you really do need the SSN, give the user 3 options:

  1. Enter the SSN every time it is needed.

  2. Encrypt the SSN and store it in the browser's localStorage

  3. Encrypt the SSN and store it on the server.

Where "encrypt" is an authenticated encryption such as AES-PMAC-SIV.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.