84

I guess the gist of my question is: Are there cases in which CBC is better than GCM?

The reason I'm asking is that from reading this post by Matthew Green, and this question on cryptography stack exchange, and this explanation of an attack on XML (since I'm encrypting json in my work, although it's not streamed anywhere, but apparently a chosen cipertext attack is possible), then I should never, ever use CBC, and just use GCM.

In other words: There's no reason to use CBC, as long as GCM exists (which it does on OpenSSL, the library I use for my encryption work). Because:

GCM = CBC + Authentication.

Could someone please tell me whether my conclusions are correct?


IMPORTANT UPDATE: Since this question is getting popular so fast, I'd like to point out from my research that GCM IS NOT A SILVER BULLET. There's huge problem with GCM, which is that if you use the same IV twice it can compromise your key (due to the use of GMAC, so it's no fool-proof). In case you're paranoid (like myself), CBC with HMAC (encrypt then MAC) is probably the best if one wants to be on the safe side. (Also please correct me if I'm wrong on this update).

6 Answers 6

67

CBC and GCM are quite different. Both are secure when used correctly, but CBC isn't as parallelizable and lacks built-in authentication. Due to this, CBC is only really practical for encrypting local files that don't need random access.

As for any advantages it might have, CBC doesn't fail as catastrophically if the IV is reused, and it can be faster if implemented on basic hardware.

As for GCM, it's basically GCM = CTR + Authentication (not CBC). It's fast and secure if used correctly, and very versatile, hence its popularity.

5
  • 1
    What do you mean with "random access" in this context? Do you mean decrypt a specific part of the file to read it? Apr 22, 2018 at 15:56
  • Yes, randomly reading pirces of the file. CTR and GCM work better for this, as the whole beginning of the file doesn't have to be decrypted.
    – Therac
    Apr 22, 2018 at 16:23
  • 12
    CBC does allow random access and parallelization for decryption. So in that respect it is no worse than GCM. You can also achieve limited parallelization for encryption with CBC by randomizing the block in the middle of your message and then compute blocks from that point forward and backwards in parallel on two threads. As for random access in GCM, you have to remember that you cannot authenticate a partial message, if you want authentication you have to authenticate the entire message.
    – kasperd
    Apr 22, 2018 at 22:36
  • 2
    @kasperd and you definitely do want authentication. Apr 23, 2018 at 12:27
  • 5
    While it is true that you technically can exploit the parallelism of CTR inside GCM to get random access to a file, actually doing so is a mistake: you can't verify the authenticator without examining the entire ciphertext, so you'd be acting on unauthenticated data, which is pure evil—don't touch it! If you want random access to a large file, you should break it up into numbered chunks of bounded size (and authenticate the number), no matter what authenticated cipher you're using. Nov 10, 2019 at 18:16
30

Big nitpick:

GCM = CBC + Authentication.

Nope, GCM = CTR + Authentication.

But in general you are right; CBC is an older mode that was invented back in the dark ages cryptographically speaking (no later than the 1970s), and is now disfavored because of the lack of built-in authentication and all the trouble that's been caused by padding oracles. One good practical example of this is that TLS 1.3 got rid of support for CBC.

GCM isn't a panacea either, however. It is strictly speaking correct, but has proven itself to be far from foolproof in practice:

  1. It fails spectacularly if you reuse a nonce. A single repeated nonce allows an adversary to recover its authentication subkey, plus to learn the XOR of the two messages with the same nonce.
  2. Its nonces are uncomfortably short (96 bits), which can be tricky to use with random nonces.

CBC doesn't have these problems. Random IVs work just fine (and are in fact required), and if you do repeat an IV you don't get catastrophic failure, you just leak information about equal plaintext prefixes.

3
  • Thanks for the explanation. Is there something better than both in openssl? Also what if I change the IV to 32 bytes, since openssl allows that for gcm? Apr 23, 2018 at 7:39
  • @TheQuantumPhysicist It is impossible to change the CBC IV to anything larger than the block size, which is 16 bytes. The IV itself actually acts as "dummy" plaintext to be encrypted first, otherwise the first block would behave like ECB. If you used Rijndael 256 (a 256-bit block variant of Rijndael, the cipher who's 128-bit block forms were standardized as AES), then you would need to use 32 byte IVs.
    – forest
    Apr 24, 2018 at 7:25
  • @forest actually I meant gcm, not cbc in my question, because 96 bits is mentioned in the answer above as a weakness Apr 24, 2018 at 13:56
14
  1. CBC is older, which means more compatibility and just overall historical reasons.
  2. There are performance advantages, if you don't need GCM for authenticity. You often may want your own system for authenticity with some additional characteristics or you may not need it at all.
1
  • Those benchmarks are for openssl which is not multithreaded. Since you cannot parallelize CBC encryption, a multithreaded implementation of GCM encryption (especially with PCLMUL) should be significantly faster. It pretty much gets the speed advantages of CTR if the CPU has PCLMUL.
    – forest
    Apr 24, 2018 at 7:23
8

Answer is written in 2018. Simply put - CBC came first. It is possible that you might have systems that only support CBC.

This would be the same question as "Why would I ever use RC4 and MD5 if AES and SHA-2 are available?" Compatibility and history. (Same with many other cipher choices.)

If all of your systems support AES-256-GCM, and have the resources to run it, and have a higher security need, then use AES-256-GCM.

For example, I have systems that do not support anything newer than SSL3, RC4 and MD5, with 1024-bit certs. (In 2018, yes). Sure, that's not much better than ROT13 these days, but it does enough for this data that doesn't actually require any encryption. (These days people call these things IoT.)

1

Four year old question, but while there are some good answers already, I'll throw another few points into the discussion:

GCM has an effective length limit for any given key + nonce pair, after which its security degrades drastically. From Wikipedia:

For any given key and initialization vector combination, GCM is limited to encrypting 239−256 bits of plain text (64 GiB).

Thus, if you're going to use GCM for large data blobs or long-running or high-traffic connections, you need to have provisions to re-initialize before this limit is hit, on both encryption and decryption. That complicates your message format or introduces an artificial length limit. In fact, even if you don't expect to run into this issue, you need to have a check in place; code that today never handles more than 4GB at a time might in future handle 100GB messages and break your security assumptions.

GCM is more fragile against bit-flipping attacks. If for some reason you don't verify the message integrity (e.g. because you tried to decrypt only part of the message, or because you are using OpenSSL and forgot to supply the authentication tag so the API just acted like normal CTR mode), an attacker can have flipped arbitrary bits in the ciphertext with the effect of precisely flipping those bits - and only those bits - in the plaintext. With CBC, flipping one or more bits in ciphertext block N will flip exactly those bits in plaintext block N+1 (and nothing else in N+1 or any subsequent block), but it will also completely scramble the plaintext of block N. Thus, bit-flipping attacks in CBC require tolerating corrupting the block proceeding the target block, or that the target block is the first block (in which case you flip the bit[s] in the IV, which works fine). This isn't a huge difference - in either case, you really need to check the message integrity, and of course GCM does that for you (if used correctly) while CBC requires having some other method (such as an HMAC) - but I have actually seen code that was "using GCM" (with OpenSSL and under the mistaken assumption that the OpenSSL API isn't an entire battleship worth of foot-cannons) but vulnerable to catastrophic bit-flipping attacks where CBC wouldn't have been at such risk (the data being tampered was JSON and the corrupted blocks would likely have been invalid to the JSON parser, preventing use of the tampered data).

GCM reveals exactly the length of the plaintext, unless you add padding prior to encryption. This is because block ciphers in counter-based modes act like stream ciphers, where the ciphertext (not counting IVs, MACs, or similar) is exactly the same length as the plaintext. CBC only adds a small amount of length masking - any message will be padded out to a multiple of the block size, which is 16 bytes for AES - but sometimes that little bit matters (though if you think that's a likely risk for you, you should pad your data to a constant length no matter what cipher you use).

Of course, that padding is a risk factor too. Used in certain scenarios, CBC runs the risk of padding oracle attacks, such as the catastrophic POODLE attack that was the death knell for SSLv3. Unlike CBC padding validation, there's no way to use GCM authentication tag validation to determine the message contents without knowledge of the key. To be fair, there are many ways to protect against padding oracle attacks and they are only a risk at all if there is something that can act as an oracle for arbitrary modified copies of a message, but the high risk of them in CBC is one reason not to use it. Of course, that's not so much a reason to use GCM in particular; there are many cipher+mode combinations that don't have this problem.

0

The attack depends one the used padding and IV handling. None of this algorithms are part of AES-CBC.

AES is a standard without IV, pad and block chain handling. AES-CBC is a standard without IV and pad handling. AES-GCM is a standard with IV, pad and block chain handling.

To use AES-CBC with a specific IV and padding without taking care, dont blame CBC, because they may be people using the weak IV and padding with another block cipyher - getting the same vulnerability.

Due to the vulnerablity of some GCM implementations to spectre attacks - I use rfc8439 ChaCha20 and Poly1305 instead of GCM.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .