25
$\begingroup$

So if I understand how an IV works with AES, I'm supposed to generate a different IV for every message because using only a key, I will get the same encryption if the message was encrypted twice (which is not secure) thus we use the IV which is some kind of a salt (some random bytes added to the encrypted message so 2 messages with the same value won't have the same encryption).

Now my question, is using the same IV for all of my messages the same as not using an IV at all? Or is it slightly better?

$\endgroup$
1
  • 17
    $\begingroup$ AES in what mode? Saying that you're encrypting something with AES is rather like saying that you're driving a Diesel engine: useful information if you're at a gas station, not so useful if you want to know how fast it goes or how safe it is in an accident. $\endgroup$ Commented Mar 20, 2018 at 13:02

4 Answers 4

48
$\begingroup$

Lets see if I can clarify things for you.

For one, the IV is not specifically related to AES at all. AES is a keyed invertible transform from a 128 bit value to a 128 bit value; that's all it can do. Now, if you just happen to have a 128 bit value that you want 'encrypted' into a 128 bit ciphertext, well, you can just use AES as is.

However, we typically want to other things than that; we may have plaintexts which aren't exactly 128 bits long; we might want nondeterministic encryption (so that if we encrypt the same value twice, it's not obvious that we did so); we might want integrity checking on our ciphertext as well.

To allow us to do those things, we use a Mode of Operation; that's a construction that uses AES (or some other block cipher) to perform these more generally useful operations. It is these modes of operation which may (not all do) take an IV.

At the moment, the most popular modes of operation are CBC and GCM; they also have very different requirements to their IVs.

So, in that context, I'll answer your questions:

I'm supposed to generate a different IV for every msg because using only a key I will get the same encryption if the message was encrypted twice

That's not the complete story; yes, if you use the same IV, same message and same key (and same AAD for GCM), you'll get the same ciphertext, but that's not the full reason.

For CBC, if you use the same IV, there are two potential problems; one is that you'll leak how the two plaintexts are related. For example, if the two plaintexts have the same first 16 bytes, and differ in the second 16 bytes, that'll be obvious to the attacker. The other is that if the attacker can predict the IV (which he can if you use the same one repeatedly), and if he can introduce his own plaintext (which can happen in some scenarios), then he can use the encryption operation as an oracle (and thus deduce the value of low entropy plaintext blocks encrypted by the same key).

For GCM, if you use the same IV, there are two different potential problems (both of which are far more serious); for one, he can deduce the bit-wise xor of the two plaintexts (which is often enough for him to deduce those plaintexts). Worse, it allows the attacker to deduce the internal authentication value, and thus allow him to modify ciphertexts (and thus the resulting plaintexts) without being detected.

Now my question, is using the same IV for all of my messages is the same of not using IV at all? Or is it slightly better?

Well, for neither mode, you don't have an option of 'not using an IV'; when you perform a CBC or GCM operation, an IV must be there (for GCM, you can have a zero length IV; that's not quite the same as 'not having an IV').

And, you didn't ask, but I'll state the general wisdom anyways:

  • For CBC mode, the IV really ought to be unpredictable to the adversary. Now, you can pick it randomly each time, or you can use (say) an AES encryption operation with the same key to generate it (which the attacker can't predict, as he doesn't have the key); both works.

  • For GCM mode, it doesn't matter in the least whether the IV is predictable to the adversary. What's critical is that you use a different one each time. If you can manage a counter (e.g. if you restart the program, you'll pick a fresh key), then using IV=0 for your first message, IV=1 for your second, etc, is the obvious approach.

$\endgroup$
6
  • 1
    $\begingroup$ I would like to thank you A LOT for this especially since I searched a lot here and on security exchange but wasn't sure if I got it right. Now I just have one last question, say I'm using CBC mode and want to pick a different IV every time, my question is that does this mean I have to save every IV for every time? I understand the concept but I'm finding it really hard to implement it. I will be putting the key somewhere safe but how am I going to pass the IV every time? (some context I'm trying to encrypt some rows in my db and every client will have his own db so every client different key) $\endgroup$
    – Ali_Nass
    Commented Mar 20, 2018 at 9:48
  • 3
    $\begingroup$ No. You can just pick a random IV. The IV for AES in CBC mode is 128 bit. The chances of picking the same IV are very small, and actually in CBC mode the ciphertext will be used for the next vector to encrypt the next block. To make sure you don't have a collision and generate the IV value anywhere you should however keep to the specified maximum of block encrypts. For AES in CBC you should change after about $2^{64}$ blocks - a terribly huge number. In general you should however design for key change. $\endgroup$
    – Maarten Bodewes
    Commented Mar 20, 2018 at 9:52
  • $\begingroup$ Should I consider this implementation safe to use? If I'm not mistaken, they are using CBC with different IV for every message and they are passing it around with the message instead of saving it somewhere safe. (for sure for me Ill generate a key and save it somewhere safe and use it when I need to) $\endgroup$
    – Ali_Nass
    Commented Mar 20, 2018 at 10:56
  • 6
    $\begingroup$ @bleh10: there is no need to 'save it somewhere safe'; it can be freely passed with the message (and that's the most common way of giving it to the receiver, actually) $\endgroup$
    – poncho
    Commented Mar 20, 2018 at 11:11
  • 1
    $\begingroup$ @bleh10 Your pointer to the implementation is NOT SAFE! It is missing the addition and verification of a checksum that ensures message integrity. HMAC is an often used mechanism for this. Always add a checksum to your encrypted byte stream, and always verify the checksum before attempting to decrypt. Otherwise your encrypted byte stream can be attacked, i.e. bits and bytes can be altered and affect your decryption! $\endgroup$
    – Sven
    Commented Mar 20, 2018 at 17:07
26
$\begingroup$

You shouldn't think of it as ‘using an IV with AES’. In fact, unless you are a cryptographer, you should forget that ‘AES’ itself exists as a thing: it is a pseudorandom permutation family $\operatorname{AES}_k\colon \{0,1\}^{128} \to \{0,1\}^{128}$, which is a technical jargon term that is practically meaningless to any application developer.

Instead, you should first identify what you are trying to do, such as send messages—arbitrary-length bit strings—from Alice to Bob who share a secret key. You should also have in mind how many messages Alice and Bob will send (a handful? a few thousand? a few quadrillion?), and how long they might be (a kilobyte? a gigabyte? an exabyte?). Then you should identify the adversary's capabilities, such as either eavesdropping on or possibly interfering with the channel from Alice to Bob. Then you should decide what security properties you want: Should the adversary be prevented from reading messages? From forging messages?

Once you have these written down in a design document for your application, then you can think about how crypto can help you.

Usually what you want is to make sure that an adversary can't read or forge messages, unless you have a very compelling reason to argue that the adversary doesn't even have the opportunity to forge messages in the first place (example: disk encryption on your laptop—if customs takes your laptop out of sight at the border, you don't really want to use that laptop again) or sell analytics about your users' conversations to authoritarian fascist regimes.

To thwart an adversary who can eavesdrop on and meddle with the channel between Alice and Bob, you should pick an authenticated cipher, or authenticated encryption with associated data (AEAD) scheme.

An authenticated cipher at the sender's end takes a key and a message (an arbitrary bit string) and some other parameters and returns a ciphertext, and at the receiver's end takes a key and a ciphertext and some other parameters and either screams FORGERY!!!1 or returns a message.

Here's an example of an authenticated cipher: AES-GCM. Don't read AES-GCM as ‘the block cipher pseudorandom permutation family AES, in the Galois/Counter mode of operation’—read AES-GCM as the following contract:

This is a contract, between you, an application developer, and AES-GCM, a spell cast by high wizards of cryptography endorsed by the United States federal government and other lesser empires.

Your obligations:

  1. You must pick a 256-bit secret key $k$ uniformly at random and keep it secret.
  2. For each message you send under the same key $k$, you must use a unique 96-bit nonce $n$ (sometimes also called initialization vector) which sender and receiver agree on for each message. (You may transmit it alongside the message, or you might infer it from context, such as a message sequence number. If Alice and Bob exchange messages in both directions, they must not choose the same nonce, so make sure, e.g., Alice uses even nonces and Bob uses odd nonces.)
  3. You must not send more than $2^{60}$ bytes of data total using the same key $k$.
  4. If you pick $n$ randomly, you must not send more than $2^{32}$ messages using the same key $k$. If you pick $n$ sequentially, you must not send more than $2^{48}$ messages using the same key $k$.

IN EXCHANGE, AES-GCM guarantees, against an adversary who can adaptively influence plaintexts sent by Alice and Bob and ciphertexts opened by Alice and Bob,

  1. The adversary cannot distinguish the ciphertexts of two equal-length messages even of their choice sent between Alice and Bob, and thus cannot read messages chosen by Alice or Bob.
  2. The adversary cannot forge messages not chosen by Alice or Bob.

If you violate any terms of this contract, the security properties provided by AES-GCM shall be rendered null and void.

The security contract for AES-CBC is a little bit different, partly because AES-CBC does not provide authentication, which are words that should scare the ever-living daylights out of you. AES-CBC is only an encryption scheme, not an authenticated-encryption scheme. AES-CBC also requires you to pad your messages, e.g. with PKCS#7 padding, which is a source of disasters called padding oracle attacks.

This is a contract between you, an application developer, and AES-CBC, a meager spell cast by early wizards of cryptography who ill-understood the consequences or persistence of the magic they were weaving in a bygone era of primordial cryptosorcery before the modern foundations on whose shoulders we now stand were built.

Your obligations:

  1. You must pick a 256-bit secret key $k$ uniformly at random and keep it secret.
  2. You must ensure your messages are always an integer multiple of 128 bits long.
  3. For each message you send under the same key $k$, you must choose a 128-bit initialization vector that is (a) unique and (b) unpredictable in advance. (You may transmit it alongside the message, or you might derive it from context, such as by a pseudorandom function of the message sequence number under another secret key shared by sender and receiver.)
  4. You must not send more than $2^{60}$ bytes of data total using the same key $k$.
  5. You must not send more than $2^{48}$ messages using the same key $k$.

IN EXCHANGE, AES-CBC guarantees, against an adversary who can adaptively influence plaintexts sent by Alice and Bob,

  1. The adversary cannot distinguish the ciphertexts of two equal-length messages even of their choice sent between Alice and Bob, and thus cannot read messages chosen by Alice or Bob.
  2. That's all. You don't get any more out of this contract, buddy.

If you violate term (3)(a) of your obligations, the adversary can tell when two ciphertexts conceal the same messages. If you violate any other terms of this contract, the security properties provided by AES-CBC shall be rendered null and void.

There are other widely deployed authenticated ciphers out there, such as NaCl crypto_secretbox_xsalsa20poly1305 or libsodium's variants, which are all-around safer than AES-GCM but have fewer imperial endorsements. There are also other spells built out of AES, sometimes colloquially called ‘modes of operation’ by cryptographers who value job security over the ability of anyone outside the high priesthood to handle cryptographic spells and user privacy and secrets and integrity, but this is not the forum for a catalog of all the spells—you need to write that design document first before we can say more about what crypto you should use if an authenticated cipher is not what you need.

Finally, to answer the question you asked: It does not make sense to fail to provide an initialization vector for an operation that takes one.

But there are some APIs that are well-designed to maximize the confusion of dear readers like you by providing an endless array of hyperconfigurable options to pick a block or stream cipher and which cipher and key length and key and mode of operation and initialization vector and nonce and authentication tag and padding scheme and message encoding and message—all this to season your indecipherable acronym soup.

In these APIs, if you fail to provide some optional function parameter specifying an IV, or if you don't call the set_iv method or what-have-you, gnomes behind the scenes might silently choose an IV for you. I recommend avoiding these APIs, or, if you must use them, treating them like nuclear waste requiring high degrees of protective gear and hand-holding by experts.

$\endgroup$
5
  • 5
    $\begingroup$ To be fair to the designers of CBC, that was done back in the '70s; the notions of what was expected from a cryptosystem was different than what it is today. Yes, CBC might not meet today's expections (that is, without help from a MAC), but to call the designers 'drunk on power' and 'selling to unwary application designers' solely because they did not anticipate requirements that were (for them) 20+ years in the future strikes me as unduly harsh... $\endgroup$
    – poncho
    Commented Mar 20, 2018 at 11:27
  • $\begingroup$ @poncho Better? $\endgroup$ Commented Mar 20, 2018 at 11:31
  • 3
    $\begingroup$ I'd go a bit further and say that you should forget that AES-CBC exists as a thing, too. What exists as a thing is e.g. AES-CBC-PKCS7, which can encrypt arbitrary byte strings (up to its length limit). Padding is too subtle to leave to the unwary. $\endgroup$ Commented Mar 20, 2018 at 21:24
  • $\begingroup$ Nuclear waste you say... $\endgroup$
    – Q-Club
    Commented Mar 21, 2018 at 2:10
  • $\begingroup$ @Gilles I agree AES-CBC as a concept exposed to application developers should largely be thrown out too. But In some sense, AES-CBC-PKCS7 is an even worse concept because a decryption oracle has secret-dependent error responses for attacker-chosen inputs, while AES-CBC does not. That said, the reason I included AES-CBC is mostly as a cautionary tale about bad security contracts—for things that an application developer is often confronted by in real APIs!—as a contrast to the considerably more useful AES-GCM contract. $\endgroup$ Commented May 19, 2019 at 4:07
4
$\begingroup$

The IV is not used for AES at all. AES has two inputs: a 128, 192 or 256 bit key and a 128 bit block of input. It generates a 128 bit block of output.

For each key each input block translates to a specific output block during encryption and the same mapping is reversed during decryption. This is called a keyed permutation as the key defines which input blocks are mapped to specific output blocks.

AES is a block cipher, but a block cipher cannot be used as a generic cipher. Encrypting the same block twice will result in the same ciphertext - leaking information to an adversary - and you can only encrypt 128 bit messages.

For this reason AES - as any block cipher - needs to be used as a function in a mode of operation. To this mode of operation is usually relatively simple compared to the block cipher; so we say that AES is used in a mode of operation.

An initialization vector (IV) or number-used-once (nonce) - I'll use just IV - is used in most modes of operation to generate a ciphertext indistinguishable from random. The specific requirements of the IV depend almost entirely on the mode of operation. The only factor of the block cipher that influences the IV value is the block size, which is fixed at 128 bits for AES.

An IV can have the following properties that depend on the mode of operation:

  • the size of the IV may differ, e.g. CBC always requires a 16 byte IV of the full block size while GCM defaults to a 12 byte IV;
  • the IV may need to be indistinguishable from random to an adversary, or it may just need to be unique (for a specific key);
  • choosing an IV may influence how many messages or blocks can be encrypted securely by the mode of operation and block cipher;

If the IV is of sufficient size then you may not need to store any information about the IV : you can just generate a secure random IV and keep it with the ciphertext. As the IV is large enough the chances of generating the same IV is small enough not to be a problem. In special cases, such as the 12 byte GCM IV, this may however limit the number of messages that should be encrypted with the same IV.

If the IV just needs to be unique then it may be possible to reuse an existing counter or identifier. For instance, disk encryption often use the specific sector as IV (or tweak, see notes). Messages in transport protocols often also contain unique sequence numbers. It is also possible to encrypt such information using a block cipher to generate an IV indistinguishable from random to an adversary. In that case it may not be needed to send the IV separately.

Usually the number of messages or blocks that may be encrypted is so high that these actual values are ignored. However, sometimes there are real limits to be taken into account. For instance using a 64 bit block cipher such as triple DES will pose you definite limits; DES can hardly be used in counter mode encryption. GCM will also pose higher but reachable limits to how much data can be encrypted with a specific key.


Notes:

  • The IV does not need to be kept secret.
  • Some block ciphers also accept a tweak and are called tweakable block ciphers, these are used in specialized constructs such as secure hashes, the Threefish block cipher in the Skein hash function is such a tweakable block cipher.
  • Information about the size and timing of the message may still be leaked; the mode of operation will not (and cannot, for indefinite length messages) protect against that.
  • Many times the mode of operation is left out as it is assumed that AES will provide all the security. Quite often this means that AES is run in CBC mode.
  • Sometimes the IV/nonce is not all that well defined, for instance CTR/SIC mode (counter mode) doesn't specify how the counter is generated from the required nonce - most implementations simply require you to generate the initial 128 bit counter value and call that the IV - which means that you can shoot yourself in the foot if the counter values are not far enough apart.
  • There are deterministic modes of encryption that do not require you to input an IV; one is called SIV mode or synthetic IV mode, here the IV is calculated by performing an operation over all of the bits of the message - even if a single bit differs the SIV mode will generate a unique IV, but the uniqueness must still be present in the message itself.
  • ECB mode also doesn't use an IV, but it is insecure for most purposes, as repeated input blocks would immediately show up.
  • In AEAD authenticated modes of operation such as GCM the IV does not need to be protected separately (put in the authenticated data) as the mode of operation itself will take care of that; If a separate message authentication code is calculated over the ciphertext then the calculation should also include the IV.
$\endgroup$
0
0
$\begingroup$

In particular, think hard about the IV in CTR mode. In CTR mode, the IV must be random every time you start up the cipher. If you start up two AES CTR ciphers under the same key, but two IVs that are not necessarily the same, but close enough to collide as you increment through the blocks.... then you have a problem. Consider encrypting two 4GB files with AES CTR under the same key because they are just different versions of the same file, but IVs only differing by 100 blocks. If you slide one ciphertext over by 100 blocks and xor them together, you will cancel out the keystream in both of them; and you will have the xor of two plaintext.

$\endgroup$

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.