In continue to my question here: How to prevent user guess the key (password), if he have access to all the data (except the key)

I thought, that instead of using sepreate IV field for each SSN (for example). I can use a prefix for that.

For example, instead of encrpyt {{ssn}}, I encrypt: {{user_id:ssn}} Every user had unique ID. So no one can find duplication in the database.

My question is: If every time I encrypt data, I am using, uniuqe prefix to the data. Is it true, that I don't need to use IV?


In your case, correct. You do not need a random IV. The combination of user_id, ssn, and your Key is globally unique, so the attacker will not be able to find duplicates from a secure algorithm. (i.e. AES-128 or higher)

Edit: IVs should always be random. While in the OP's case it may not be that important, it usually is, and is easy to implement, so use random IVs. See comments.

It's worth noting that you are not using a chaining algorithm because the amount of data you are encrypting is so small. This reduces what you have to worry about. The purpose of the IV is to make sure the first 'block' is unique, and the purpose of the Chaining Method is to make the remaining blocks appear random so there is no discernible pattern in long data.

But your data fits into one block (128 bits for AES-128) so that is not necessary.

  • This answer is flatly incorrect. Prefixing the user_id to the plaintext will still lead to deterministic encryption, because encrypting the same user_id and ssn with the same key twice will produce the same ciphertext. Or, in terms of semantic security, when the attacker sees the same ciphertext in two different contexts they will be able to tell that the user_id/ssn pair is the same in both. – Luis Casillas Nov 17 '16 at 21:43
  • @Aminadav, Luis has pointed out that if the attacker can cause an SSN to be updated (and encrypted) for an arbitrary (existing) user_id then he could determine what SSN was used by brute-forcing the (low-entropy) SSN itself and looking for a matching encrypted result. (still never determining the key) While, in your case, this may not be possible in most attack scenarios, you might be better off to use a simple random int instead of user_id, to reduce the risk of SSN theft via this means. – 700 Software Nov 17 '16 at 21:49
  • 1
    @LuisCasillas, You have a good point here, though I would not have called it "flatly incorrect" simply because it only becomes relevant with a combination of attack vectors. i.e. unauthorized updates to existing users w/o being able to see their data and theft of encrypted data (e.g. SQLi) and not theft of the key itself. Only in that specific scenario is your comment relevant. – 700 Software Nov 17 '16 at 21:54
  • @GeorgeBailey: Your answer affirms that the "unique" prefix means you don't need the IV, but the "unique" prefix suggested in the question is only so in a per-user basis. Ciphers that require unique IVs need them to be unique to each encryption with the same key. So I must insist, "unique" IDs as the questioner describes them are not a substitute for IVs. – Luis Casillas Nov 17 '16 at 22:19
  • @GeorgeBailey: And there's another, much bigger problem, which is that you haven't asked at all cipher or mode the questioner intends to use. And with some ciphers (e.g., AES-CTR), IV reuse leads to catastrophic loss of confidentiality. But more generally, you're encouraging the questioner—who clearly is not in a position to implement this system securely—to risk the Social Security numbers of unknown numbers of persons. – Luis Casillas Nov 17 '16 at 22:23

This question cannot be answered without knowing what cipher or mode is in use, because different ones have different requirements on their IVs, and different failure modes. There are two general cases here:

  1. Ciphers that require unique IVs.
    • AES-CTR is a prime example. The failure mode for IV-reuse here is catastrophic loss of confidentiality: an attacker may likely be able to decrypt all of your values.
  2. Ciphers that require random IVs.
    • AES-CBC is a prime example. The failure mode for IV reuse is loss of semantic security—same plaintext encrypted twice produces same ciphertext, so the attacker can tell that the same ciphertext in two different contexts stands for the same plaintext.

So clearly, if you're using something like AES-CTR you must use unique IVs, there's no getting around it. More generally, you must follow the instructions for the specific ciphers you're using—which you haven't even told us—instead of trying to invent an ad-hoc way not to. (That should be an enormous red flag!)

Second, you're playing fast and loose with the idea that you're using a "unique" prefix, because you're describing this prefix as user_id. But that implies that the prefixes you have in mind are unique for each user. But what ciphers normally want you to use is an IV that is unique for each encryption operation—if you encrypt the same plaintext twice, you're expected to supply two different IVs so that the encryptions will produce different ciphertexts.

Third, your concerns about "duplication" are on the wrong track. Depending on what you mean by that (which is unclear!):

  • If you use random IVs and prepend them to the plaintext, there cannot be duplicate ciphertexts at all, because ciphers are injective—every encryption can be "undone" and you're guaranteed that you get the original plaintext back. This implies that duplicate (IV, ciphertext) pairs are impossible.
  • If you're concerned that encrypting the same plaintext twice in different contexts will produce "duplicate" ciphertexts, your proposal to prefix the user_id will not solve that! Encrypting the same {{user_id:ssn}} plaintext twice will always produce the same ciphertext anyway.

I said this in my answer to your other recent question, and I repeat it: you should not go ahead with your plans to implement the security for your application. You need professional, expert help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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