4
$\begingroup$

My question is (hopefully, for somebody) a simple one; but my project is holding as I'm not sure.

I read on SO that generating encryption keys without an IV is a bad idea, so is using a constant IV as the first part of any cipher block will be the same across multiple encryptions.

If you're encrypting a single file (a private key for local disk storage for example) is it safe to use a constant IV (as the users password will vary)? The problem is, every time I rehash/generate the encryption key from the plain text password, a new random IV is generated resulting an a completely different decryption key for that file.

$\endgroup$
4
  • 1
    $\begingroup$ Just to clarify: you store some number of files, each of which is encrypted with the same IV but different passwords? And also I'm not sure I understood the part about rehash/generate the encryption key from the plain text password, could you clarify what you mean? $\endgroup$
    – n1ckolas
    Jun 4, 2013 at 13:08
  • $\begingroup$ Sorry, I am using a method to take take the plain text password hash, it generates an IV, combines the two and returns the encryption key as base64. I encrypt the file with this. When I decrypt the file, to get the key from the plain text password, I repeat the process but a new IV is created, resulting in a difference encryption key. So as it was a single file, I figured a constant IV would be acceptable. BUT... since reading more on SO, I see the practice of storing the IV in the encrypted file is OK? So I now have a "constant" IV when coming to decrypt the file. This is OK isn't it? $\endgroup$
    – Jonny Wilson
    Jun 4, 2013 at 13:43
  • 2
    $\begingroup$ Simply store the IV alongside data you encrypt. There is no requirement for the IV to be secret. Also, I hope you're using something like bcrypt or PBKDF2 for generating a key from the user's password. $\endgroup$ Jun 5, 2013 at 22:51
  • 2
    $\begingroup$ Related to this simpler question with a simple answer. $\endgroup$
    – fgrieu
    Jun 6, 2013 at 5:11

2 Answers 2

8
$\begingroup$

As already mentioned by fgrieu in a comment, you seem to be mixing up the initialization vector for the cipher with the salt for the key derivation. They play similar roles — both are here to insure that different values of the IV/salt lead to different keys/ciphertext — but they are used in different ways and they have different security properties in this scenario.

When you generate a key from a password, the number of likely passwords is far less than the total number of possible keys. A pretty good password may have 44 bits of entropy; a password used in the wild tends to have a lot less. Compare to 128 bits of entropy in a randomly-generated AES-128 key. This makes the key space vulnerable to brute force search (“I'll derive the key for password1 and try to decrypt. Nope. swordfish? Nope. Tr0b4dor&3? Nope. Tr0b4dor&4? Win!”).

In order to mitigate this problem, deriving a key from a password must include two elements:

  • Slowness, because spending .1s instead of .1ms to derive the key when the user types his password isn't a performance problem, but it multiplies the work needed by an attacker by 1000.
  • Uniqueness, so that an attacker cannot precompute all the keys derived from likely passwords and then crack a lot of password-encrypted files by a simple table lookup.

The issues are the same as password hashing — and indeed most password hashing schemes are password-based key derivation algorithms.

To derive a key from a password, you need a password-based key derivation function, which includes a step of key stretching for slowness and uniqueness. The salt, which provides uniqueness, is an input to the KDF, alongside the password. bcrypt, PBKDF2 and scrypt are the three recommended password-based key derivation algorithms nowadays; scrypt has the nicest properties (it's less easy to brute-force with dedicated hardware) but is still a bit new.

The salt must be unique for everybody who uses the same KDF, not just among your files. The best way to ensure this is to have a sufficiently long random salt.

All message encryption algorithms use an IV or nonce to ensure that if you encrypt the same message twice, this isn't visible in the ciphertext (at least the algorithms that are semantically secure — it is occasionally useful to sacrifice this property in the interest of deterministic encryption but that applies to specialized scenarios). If you only ever encrypt one message with the same key, you don't need an IV — the standard thing to do in this case is to use an all-bits-zero IV.

If you only ever encrypt one file with the same key, you don't need an IV. Do consider that if you use the same key for multiple versions of the file, you should use an IV. You may want to derive a new key with a new salt in this situation, though.

$\endgroup$
0
$\begingroup$

I have opted to generate a random IV but store this in the front of the encrypted file. I can then pull this and use it to recreate/generate the Rijndael key to decrypt the file. In testing this create a new and completely random Cipher Block each time.

$\endgroup$
3
  • 1
    $\begingroup$ Doesn't that mean anyone else who gets this file can also generate the key? $\endgroup$
    – Chris
    Jun 4, 2013 at 14:51
  • 1
    $\begingroup$ Only if they have the pass phrase to accompany the IV. The method generates the key from the pass phrase hash and the IV. The IV is only used for the randomisation of the cypher text. $\endgroup$
    – Jonny Wilson
    Jun 4, 2013 at 15:48
  • 4
    $\begingroup$ In the common definition of the term, an IV does not influence the key. What you have here is a nounce or salt to a KDF, not an IV. Beware that a KDF using a password as the master key has a special requirement: slow down password search; see scrypt for a good one. $\endgroup$
    – fgrieu
    Jun 6, 2013 at 5:09

Your Answer

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

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