Due to protocol limitations, I can put in 24 bytes of data only for tx (excluding headers), if I use AES_GCM for encrypting my data, I understand I don't need to worry about padding.

For instance, if my data is 22 bytes, I would be getting a 22 bytes encrypted output. So, I had zero-ed in on AES-GCM or AES-CTR. However, I have observed AES-CTR stream cipher is not available in Microsoft crypto library and hence decided on using AES-GCM. But then again, I have observed that output of AES-GCM is cipher text and tag. The value of this tag field is recommended to be minimum of 32 bytes. I had initially thought of using 2 bytes of CRC so my data would be like this:

ciphertex + CRC16 = 24 bytes.

But when I read about AES-GCM, I observed that the tag field is doing the same job as CRC. If I specify, a tag length of 2 bytes for encryption, will it be okay? The other option would be to use CRC16 as it takes only 2 bytes.

Another info is my key/IV pair keep changing every 1 hr. Please suggest what's the best way out - which encryption method is best

  • $\begingroup$ AES-GCM doesn't support a 256-bit tag. Are you referring to HMAC with AES-CTR? Do you need authentication for your protocol? A 2 byte tag is near useless, and it doesn't sound like the protocol was designed for such a use case. $\endgroup$ Mar 13, 2023 at 16:09
  • $\begingroup$ Remember: It's always easy to find collision in CRC, even with CRC32. $\endgroup$ Apr 12, 2023 at 14:01

2 Answers 2


If I use AES_GCM for encrypting my data, I understand I don't need to worry about padding.


If my data is 22 bytes, I would be getting a 22 bytes encrypted output.

That's not accounting for the Initialisation Vector. The usual size of that is 12 bytes, usually as a header of the ciphertext. You can reduce it's size (and have the receiver pad with zeroes), but it must remain wide enough that IV won't be reused. That can be a counter. If the payload has fields that need not be encrypted and change at each use (e.g. time guaranteed monotonic because it survives reset), they can be safely used as IV (and removed from what's encrypted).

The value of this tag field is recommended to be minimum of 32 bytes

No. The tag field is a maximum of 16 bytes (128 bits). Reducing it to 4 bytes (32 bits) is OK in some applications. If the tag is $b$-bit, making $n$ attempts at getting a bogus message accepted by a verification device will result in one being accepted with probability no more than $n/2^b$. For example, with a 4-byte tag, if adversaries submit one message per millisecond for one day, their probability of success is 2%.

There's no a hard limit to the minimum tag size (unless enforced by some API). If you reduce it to 2 bytes, adversaries that submit one message per second for one hour have probability of success 5.5%. If your accepting device locks after a small number of errors, that might be acceptable (but that's at the expense of availability/resistance to denial of service).

Other option would be to use CRC16

No! Do not use AES-CTR (or equivalently AES-GCM without tag) on data protected by a CRC16: adversaries that got hold of one message can alter it into another message that will be accepted, in a basic attack exploiting the linearity of CRC and CTR encryption.

My key/IV pair keep changing every 1 hr

Don't do this if you encrypt more often than once per hour! A key/IV pair must not be reused. AES-GCM (and AES-CTR) are extremely vulnerable to that. It's even in theory not recommendable to reuse an IV if the AES key is 128-bit, for it allows multi-target attack.

Again, you must figure out a way to have the IV change at each encryption, at least if the same key is reused. The two most standard ways to do it are:

  • A wide random IV (the standard is 12 bytes), which you won't like.
  • Using AES-GCM-SIV, but overhead is even worse.
  • A dedicated counter, which can be narrower (e.g. 2 bytes), but must be such that it won't repeat (for a given key). Things to be considered include ability for adversaries to reset the device/counter, or make it overflow and cycle.
  • Using some field of the data that needs not be encrypted and naturally changes and does not repeat (for a given key). That's your best bet I guess.

You might also be able to save some space by using a better encoding of the data before encryption. For example, 12 decimal digits fit 5 bytes.

  • $\begingroup$ The non-negligible probability $n/2^{b}$ of a bogus message being accepted is due to the encryption oracle the adversary may have access to. Doesn't a CRC appended to the ciphertext give a decryption-failure oracle that leaks information about the cleartext? Wich can raise more problems beyond DoS attacks. Is that correct? $\endgroup$ Apr 12, 2023 at 13:34
  • 1
    $\begingroup$ @CryptoLearner: the $n/2^b$ probability assumes no encryption oracle, only sending messages with distinct tags (e.g. incremental). Appending a CRC of the plaintext to the ciphertext directly leaks info about the plaintext, without a decryption oracle. Appending a CRC of the ciphertext to the ciphertext leaks nothing, but has no cryptographic interest (it only detect transmission errors). The answer discusses appending a CRC of the plaintext to the plaintext before encryption (very poor in CTR, common if not really recommendable practice in CBC mode). It may cause leak with decryption oracle. $\endgroup$
    – fgrieu
    Apr 12, 2023 at 13:44
  • $\begingroup$ yep. I see now. I didn't write my point in my question accurately, but you answered it here: appending a CRC of the plaintext to the plaintext before encryption [...] It may cause leak with decryption oracle $\endgroup$ Apr 12, 2023 at 14:25

CRC16 is linear and would be disastrous if we entrust authenticity to it, so truncating the tag to 2 octets would be the way to go (as long as it's sufficiently secure for your purpose).

IV MUST change for each invocation of encryption - otherwise it's reusing "cipher stream", and it's trivially breakable.


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.