HelloWorld
HelloWorld

Reputation: 1863

Does the IV of AES-128-cbc need to be random during encryption and decryption?

I am using node and the crypto module to encrypt and decrypt a large binary file. I encrypt the file using crypto.createCipheriv and decrypt it using crypto.createDecipheriv.

For the encryption I use a random IV as follows:

   const iv = crypto.randomBytes(16);
   const encrypt = crypto.createCipheriv('aes-128-cbc', key, iv)

What I don't understand, do I need to pass a random IV for createDecipheriv as well? The SO here says:

The IV needs to be identical for encryption and decryption.

  1. Can the IV be static? And if it can't, is it considered to be a secret? Where would I store the IV? In the payload?

  2. If I use different random IVs for the encryption and decryption, my payload gets decrypted but the first 16 bytes are corrupt. This means, it looks like the IV needs to be the same but from a security perspective there is also not much value as the payload is decrypted except 16 bytes.

Can anyone elaborate what the go-to approach is? Thanks for your help!

Upvotes: 0

Views: 4070

Answers (2)

TheGreatContini
TheGreatContini

Reputation: 6629

For security reasons, the IV needs to be chosen to meet cryptographic randomness security requirements (i.e. use crypto.randomBytes( ) in node). This was shown in Phil Rogaway's research paper. The summary is in Figure 1.2 of the paper, which I transcribe here:

CBC (SP 800-38A): An IV-based encryption scheme, the mode is secure as a probabilistic encryption scheme, achieving indistinguishability from random bits, assuming a random IV. Confidentiality is not achieved if the IV is merely a nonce, nor if it is a nonce enciphered under the same key used by the scheme, as the standard incorrectly suggests to do.

The normal way to implement this is to include the IV prepended to the ciphertext. The receiving party extracts the IV and then decrypts the ciphertext. The IV is not a secret, instead it is just used to bring necessary security properties into the mode of operation.

However, be aware that encryption with CBC does not prevent people from tampering with the data. If an attacker fiddles with ciphertext bits within a block, it affects exactly two plaintext blocks, one of which is in a very controlled way.

To make a very long story short, GCM is a better mode to use to prevent such abuses. In that case, you do not need a random IV, but instead you must never let the IV repeat (in cryptography, we call this property a "nonce"). Luke Park gives an example of how to implement it, here. He uses randomness for the nonce, which achieves the nonce property for all practical purposes (unless you are encrypting 2^48 texts, which is crazy large).

But whatever mode you do, you must never repeat an IV for a given key, which is a very common mistake.

Upvotes: 0

Rob Napier
Rob Napier

Reputation: 299425

The Key+IV pair must never be duplicated on two encryptions using CBC. Doing so leaks information about the first block (in all cases), and is creates duplicate cipher texts (which is a problem if you ever encrypt the same message prefix twice).

So, if your key changes for every encryption, then your IV could be static. But no one does that. They have a key they reuse. So the IV must change.

There is no requirement that it be random. It just shouldn't repeat and it must not be predictable (in cases where the attacker can control the messages). Random is the easiest way to do that. Anything other than random requires a lot of specialized knowledge to get right, so use random.

Reusing a Key+IV pair in CBC weakens the security of the cipher, but does not destroy it, as in CTR. IV reused with CTR can lead to trivial decryptions. In CBC, it generally just leaks information. It's a serious problem, but it is not catastrophic. (Not all insecure configurations are created equal.)

The IV is not a secret. Everyone can know it. So it is typically prepended to the ciphertext.

Upvotes: 1

Related Questions