In Signal Protocol when you use a Double Ratchet you have 2 options:

  1. Normal encryption = header + ciphertext
  2. Encrypted header encryption = encryptedHeader + ciphertext

The encrypted header encryption has the advantage of encrypting the public ratchet key pair and counter, this can also encrypt the message mac and possibly the ciphertext length encase needed over a network.

When encrypting a header you must have an initialization vector (aka IV) since the key will only change once receiving a new ratchet key pair (when moving a step in the DH ratchet (specified in the Double Ratchet documentation)).

You can read more about the function that header encryption must follow in DoubleRatchet - External Functions.


  1. The header will be encrypted with "AES/CBC/PKCS5Padding" (in Java PKCS5Padding is actually PKCS7Padding) as specified in Java or in normal cryptography AES with CBC mode and PKCS7Padding as the padding
  2. The ratchet public key is 32 bytes

From what I can think of I have 3 options for choosing the initialization vector now:

  1. Generate a new 16 byte initialization vector and prepend it before the header
  2. Take the first 14 bytes of the current ratchet public key (NOTE: the ratchet public key changes every DH ratchet step) and append the current counter as a short (NOTE: the counter increments every message and resets to 0 every DH ratchet step) which should generate a unique initialization vector, tho mostly predictable (NOTE: this is mostly predictable because this is considering if they actually have the ratchet public key and counter, with header encryption they are encrypted so they should be unknown to a malicious party)
  3. Use the second option just with instead of taking the first 14 bytes of the ratchet public key taking for example the first 30 bytes (will result in 32 once appending the counter) or even the whole key.

So my question is, which should I choose?

Things to consider:

  1. The first option gives a more random value, yet exposes it and also take 16 bytes more space.
  2. The second option gives a less random value tho the first 14 bytes will still look random, the initialization vector is not exposed which possibly increases security and takes 16 bytes less space
  3. Third option results in a bigger initialization vector making it more random

1 Answer 1


The security contract for AES-CBC is that the initialization vector must be uniform random and unpredictable in advance—mere uniqueness is not enough (nor even necessary).

It is safe to choose the IV as a pseudorandom function of a unique nonce, or even as a pseudorandom permutation of a unique nonce, which the sender and receiver can agree on—e.g., they could choose it to be a message counter, if they are both capable of counting—without sending any explicit IV over the wire. Indeed, you could even use a message counter encrypted with AES under the same key, as long as the attacker has no control over the counter.

It is not safe to choose the IV as anything that an attacker can predict in advance, like a public key previously sent over the wire and a predictable counter.

  • $\begingroup$ Thank you for the detailed answer, but just making sure is there even an advantage to a secret initialization vector? $\endgroup$ May 25, 2019 at 2:28
  • $\begingroup$ There's no advantage to keeping the AES-CBC IV secret after the fact; it simply must be unpredictable by the adversary in advance before the sender encrypts and sends a message. $\endgroup$ May 25, 2019 at 2:47

Your Answer

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

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