I am developing a symmetric en-/decryption routine written in c# for a database containing user-specific, sensitive information.

I have narrowed down the implementation to 3 different approaches, but simply cannot determine which is the "best". So, which of these is the most secure?

  1. AES in GCM mode. Using either BouncyCastle or CLR Security implementation. For those who don't know, GCM mode utilizes CTR mode with a provided counter (not sure of the exact implementation) and an additional message authentication process (definitely not HMAC)

  2. AES in CTR mode. Using Bouncy or CLR security again. In this instance I would use the .net HMAC and utilize a 16 byte IV randomly generated (securely) as the unique nonce.

  3. AES in CBC mode. Using the .NET implementation. Again the HMAC from .net and rand IV.

The simpler the better cause I'll probably mess it up

Thanks a bunch

  • $\begingroup$ The MAC in AES-GCM isn't HMAC. $\endgroup$ Jul 10, 2012 at 21:40
  • 4
    $\begingroup$ "The simpler the better cause I'll probably mess it up" Stop right there, if you are not confident in being able to get it right then hire somebody else to do it, particularly if you are working with real-life sensitive data. Please (unless this is a fictional scenario just for learning, of course) $\endgroup$
    – Thomas
    Jul 10, 2012 at 22:02

3 Answers 3


GCM mode is best, as it can not be attacked using padding oracle attacks, which are much more common than commonly thought. It is also the only one providing integrity protection, something that is certainly much overlooked.

Make really sure your NONCE is random though, or use one that is uniquely defined (even in time) within the database.

SquareRootOfTwentyThree makes a valid objection to say that the comparision should have been between GCM mode and symmetric ciphers + HMAC. There are several reasons why I would favor GCM mode over HMAC:

  • two separate/unrelated keys are needed for encryption and HMAC
  • you need to match the security of the hash in the HMAC with that for encryption
  • there is more room for error when using HMAC (provide a MAC over the wrong data)
  • you need to communicate two different algorithms to the other party
  • you need to check if HMAC is actually performed

This is opinionated as all can be made secure.

The last point about the HMAC check sounds obvious, but see what happened to XML encryption in WS-security where in most implementations the signature validation could be switched off, leading to padding oracle attacks. Creating a protocol that simply performs GCM mode has fewer points of failure.

Note that the drawback regarding the NONCE mentioned by CodesInChaos is a valid one. Unfortunately any of these algorithms is affected if the IV or NONCE is not used correctly.

GCM is started to be used by updates of several protocols (TLS, XML encryption) and has been approved by NIST.

  • $\begingroup$ Mind you, both CTR and GCM have a small drawback in that they leak more information about the size of the plain text (defined to a single octet instead of a block size). $\endgroup$
    – Maarten Bodewes
    Jul 10, 2012 at 22:50
  • 2
    $\begingroup$ The comparison was between GCM and CTR/CBC+HMAC, not between GCM and pure CTR/CBC. In that sense, oracle attacks are defeated in all three cases, isn't it? $\endgroup$ Aug 3, 2012 at 7:12
  • $\begingroup$ @SquareRootOfTwentyThree hmm, I'm emberrased to say you are correct. Never mind, I still think GCM is best, added the reasons. $\endgroup$
    – Maarten Bodewes
    Aug 3, 2012 at 7:57

IMO AES-CTR+HMAC is more secure than AES-GCM. The most significant difference is that AES-CTR+HMAC relies on the nonce for confidentiality but not for integrity. AES-GCM on the other hand relies on the nonce for both. So nonce failures are much more severe with AES-GCM.

The main advantage of AES-GCM is that it's significantly faster.

  • $\begingroup$ I'm using a 12 byte nonce randomly generated, so thats 2^96 possibilities. And the standard is a probability of collision less than 2^-32. So I believe that is a large enough margin that I may assume no IV will repeat. Given that, would you still go CCM? $\endgroup$
    – crawfish
    Jul 13, 2012 at 19:11
  • 1
    $\begingroup$ A 12 byte nonce is pretty short. It becomes dangerous once 2^48 messages get generated with the same key. I already feel uncomfortable with 16 byte nonces in some situations. I'm also somewhat paranoid about PRNG failures. $\endgroup$ Jul 13, 2012 at 19:17
  • 1
    $\begingroup$ Another practical advantage is that HMAC is already implemented in .net, but you need to implement GCM yourself. $\endgroup$ Jul 13, 2012 at 19:18
  • $\begingroup$ HMAC is implemented, but CCM is not, so I would have to combine them myself. I already wrote the encrypt/decrypt routines here in my more recent post. I just used an external library. Its currently in gcm but can be switched to ccm easily $\endgroup$
    – crawfish
    Jul 13, 2012 at 19:35
  • 2
    $\begingroup$ CBC then MAC obviously does not have padding issues, as long as you verify the MAC before decryption. $\endgroup$
    – Maarten Bodewes
    Aug 3, 2012 at 22:47

I would say that CBC+HMAC mode is the best of the three (although not the fastest), because of the various security requirements on the IV/nonce.

For GCM and CTR, the counter must be unique, for every pair encryption key/plaintext. I assume the key will be always the same. Uniqueness is very difficult to securely achieve in practice. If you rely on some storage for keeping track of what you have used in the past so far, you are exposed to unauthorized or accidental modifications of such storage that may roll back your log to a previous state. If you rely on probability (that is, you generate the nonce randomly) you are exposed to attacks or flaws of the RNG. In either case, failure to comply to uniquess is absolutely catastrophic (since an attacker can infer the XOR or different plaintexts).

For CBC, the IV should be unpredictable. You are still dependent on the quality and security of the RNG (which can be mitigated by having the hash of the data to contribute to the IV), but failure is typically less serious: an attacker may only infer at which point plaintext blocks differ.

  • $\begingroup$ OK, we now have answers recommending each of the three options. Let the voting begin! :) $\endgroup$ Aug 3, 2012 at 14:29
  • $\begingroup$ @IlmariKaronen can't vote my own answer up, so I'm all out :) $\endgroup$
    – Maarten Bodewes
    Aug 4, 2012 at 21:33

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.