In Signal Protocol when you use a Double Ratchet you have 2 options:
- Normal encryption =
header + ciphertext
- 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.
NOTES:
- 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
- The ratchet public key is 32 bytes
From what I can think of I have 3 options for choosing the initialization vector now:
- Generate a new 16 byte initialization vector and prepend it before the header
- 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) - 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:
- The first option gives a more random value, yet exposes it and also take 16 bytes more space.
- 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
- Third option results in a bigger initialization vector making it more random