10

The situation is that I want to use symmetric encryption to store some info in files. I'm going to use AES-CBC algorithm. The user is going to remember the password (meaning it will not be stored anywhere but in the brain of the owner of the files) however I'm worried about the management of the salt and the IV.

From several sources I've seen that the salt must be unique and never reused (which imples using a cryptographically secure pseudorandom number generator) but it can be safely appended in clear text to the encrypted data. Is this right?

For the IV I have seen two different approaches:

  • Similar to the salt, generate in randomly and store in clear text.
  • Derive it from the password and salt, the same way it is done with the key used to encrypt each block via the AES algorithm.

Which is the preferred / safest way?

Raoul722
  • 3,003
  • 3
  • 23
  • 42
Jordi
  • 203
  • 1
  • 2
  • 7

3 Answers3

6

Generate a random IV (with a cryptographically secure random generator of course) and prepend the IV to the ciphertext.

Some modes of encryption don't require a random IV, but you can never go wrong with a random IV as long as your RNG works fine. An IV does not need to be secret (it's a matter of terminology — if it had to be secret it woulnd't be called an IV).

In the case of CBC, a non-random IV is safe if the key is only ever used for a single message. Your key is apparently derived from a user password and a salt, which makes it unique for this password-salt combination — but are you always going to generate a new salt when you encrypt a new version of the file? Even if you currently do this, are you sure that version 3 of your program isn't going to do things differently and encrypt several files with the same key?

Use a random IV, generated independently from the salt. The maintenance cost is negligible and arguably negative (it's one line of code, less long than the comment explaining why it would be safe to use a non-random IV), the performance cost is negligible.

Don't forget that CBC only ensures confidentiality, it doesn't protect the file against modification. Strongly consider using an authenticated encryption mode instead, which protects both the confidentiality and the authenticity of the data.

Finally, or rather firstly, there are already plenty of libraries and plugins to do this out there — do you really need to reinvent the wheel?

5

With AES-CBC you usually need a random IV. However, in the case where you use each key only once, like when using password-based encryption with random salts for each file, you can use a fixed, zero IV. So as long as you use a new salt for each file – and even new versions of the same file – you can forgo storing an IV and just use a zero block.

Note that CBC alone will not prevent an attacker from modifying the encrypted file. So you may want to consider whether you also need authentication (i.e. a ).

(BTW, in practice you probably want to prepend the salt, not append, for convenience and maybe performance.)

otus
  • 32,462
  • 5
  • 75
  • 167
1

If you're generating the encryption key from the password and a salt with something like PBKDF (or anything else with an extensible output), you can get an IV for free with the same key-derivation process. That will save the (minor) trouble of storing another field in the file, any suspicion on the predictability of the IV, and has the advantage that you can easily generate another key for a MAC with the same system, if you ever need one.

In any case, with a password, you should be using some slow key stretching method to slow down dictionary against on the password.

ilkkachu
  • 912
  • 6
  • 13