8

During my encryption app i've got the password creation bit:

PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10000, keyLength);

and later on the actual encryption part:

cipher.init(Cipher.ENCRYPT_MODE, secret, ivSpec);

The initialisation vector need random bytes, the salt needs random bytes, can I use the same (cryptographically secure) random bytes for the salt and the IV or would that weaken the encryption somehow? - It would make storage a little easier if I could.

I'm not talking about reusing the IV or the salt over multiple messages, for each separate message a new array of bytes would be generated, but could I for each individual message double up and use the same newly generated bytes for both the salt + the IV?

EG:

Message 1: Random bytes = h6ds .... Salt = h6ds / IV = h6ds

Message 2: Random bytes = djs9 .... Salt = djs9 / IV = djs9

Message 3: Random bytes = 9sdf .... Salt = 9sdf / IV = 9sdf

... and so on

Crizly
  • 2,607
  • 4
  • 18
  • 29

2 Answers2

10

The IV should be unique for every message encrypted, so no, if you intend to encrypt more than one secret using the key you generate from this password, you cannot reuse the salt as the IV. Reusing an IV at best leaks information about the plaintext, and at worst, can destroy your encryption scheme altogether (depending on the mode you're using) and so yes, in any case if it is reused, it will indeed weaken the encryption.

If, however, you are not reusing it, and it will only be used a single time, then no, the fact that the same random value serves as a salt elsewhere should have no effect on the strength of the encryption at all.

Edited to add: There is a one caveat that I don't believe applies in this specific case, but should mention. Since you are using a KDF to generate the key, the salt constitutes a part of the strength of the key. If the IV is being exposed to the attacker (Given the wording of the question, I don't think that's the case here) then you make the attacker's job considerably easier when it comes to being able to compute candidate keys, and keys generated from weak passwords become susceptible to dictionary attacks. If the salt/IV is merely being stored, however, and compromise of one can be reasonably considered to compromise both, then the initial premise that the strength is not effected still holds.

RoraΖ
  • 12,347
  • 4
  • 51
  • 83
Xander
  • 35,616
  • 27
  • 114
  • 141
  • I wouldn't be reusing the IV in multiple messages, i mean for each individual message could the IV be the same as the salt? - for the next message the randomly generated bytes would be different – Crizly Oct 27 '14 at 22:04
  • @Crizly The rules for an IV state that the IV should be unique for a given key. So, if you're not reusing the IV for encryption, I don't see why it would be a problem for it also to be a salt. I'll add this to my answer. – Xander Oct 27 '14 at 22:06
  • Although it does seem suspect that you would re-derive a key from a low-entropy password for every crypto operation. Typically, one would compute a long-lived encryption key using a passphrase and salt, then re-use that key to encrypt multiple messages (using unique IVs). – Stephen Touset Oct 27 '14 at 22:23
  • 1
    @StephenTouset It is unusual, but possible if there's only one piece or set of data that must be encrypted for each user. – Xander Oct 27 '14 at 22:28
2

Using the salt for PBKDF2 as IV for an encryption run which uses the key obtained from PBKDF2 relies on PBKDF2 operating like a random oracle, thereby "isolating" the two usages from each other, preventing bad interactions to happen. This is not a much studied property, but it is plausible, given that PBKDF2 is a lot of nested calls to HMAC, and HMAC is the usual candidate for a random oracle.

However, another design is simpler to analyze: simply have the KDF produce enough bytes for the key and the IV. I.e., from the salt and password, generate 32 bytes: 16 bytes for the encryption key, and 16 other bytes for the IV. That way, you keep the storage bill at the same level (only one salt, no extra space for the IV) and it becomes somewhat obvious that you are doing no funky business with your IV. As an additional bonus, if you switch the KDF to another one with strict requirements on salt value and size, you can still get an IV of appropriate length for your encryption.

Usual caveats apply:

  • PBKDF2 is not a very good password-based key derivation function. In particular, its running time increases proportionally to the output size (with thresholds), meaning that getting more than 20 bytes out of PBKDF2 may force you to halve the number of iterations, which is detrimental to security. Also, PBKDF2 is easy to optimize on a GPU. Bcrypt would be a better choice; for the "arbitrary output length" part, couple the password-hashing function with a good (fast) KDF such as HKDF.

  • When you do encryption you probably need a MAC too. This can be tricky business.

Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955