1

i want to generate a 12 bytes authentication in AES-GCM. my code only give me an output tag of 16 bytes. i have tried to use the min_tag_length but it rises an error. can i get your guidance, thank in advance.

import os
from cryptography.hazmat.primitives.ciphers import (
    Cipher, algorithms, modes
)

#f(StoC)= SC || IC || GMAC( SC || AK || StoC)
#associated data , AAD= SC || AK || StoC
SC=bytes.fromhex("10")
StoC=bytes.fromhex("39373635313934303931363137383231")
key = bytes.fromhex("000102030405060708090A0B0C0D0E0F") #EK
A_key = bytes.fromhex("000102030405060708090A0B0C0D0E0F") #AK
#AAD
associated_data=SC+A_key+StoC
#print (associated_data.hex(),type(associated_data))


def encrypt(key, plaintext, associated_data):
    #global associated_data
    #global key

    # Generate a random 96-bit IV.
    part1 = bytes.fromhex("485845033225519F") #Syst_title
    part2 = bytes.fromhex("00000002") # IC

    # Concatenate the parts
    iv = part1 + part2

    #iv = bytes.fromhex(sum)
    #print (type(iv))

    # Construct an AES-GCM Cipher object with the given key and a
    encryptor = Cipher(
        algorithms.AES(key),
        modes.GCM(iv, tag_length=12),
    ).encryptor()

    # associated_data will be authenticated but not encrypted,
    # it must also be passed in on decryption.
    encryptor.authenticate_additional_data(associated_data)

    # Encrypt the plaintext and get the associated ciphertext.
    # GCM does not require padding.
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()
    iv_hex=iv.hex()
    ciphertext_hex = ciphertext.hex()
    encryptor.tag_hex= encryptor.tag.hex()
    print(f"{iv_hex=}")
    #print(f"{ciphertext_hex=}")
    print(f"{encryptor.tag_hex=}")

    challenge =SC+part2+encryptor.tag
    challenge_hex=challenge.hex()
    print(f"{challenge_hex=}")

    #return (iv, ciphertext, encryptor.tag)
    return challenge_hex

encrypt(key, StoC, associated_data)

2
  • See the line in the script where you are calculating the AAD: associated_data=SC+A_key+StoC, by adding together SC, A_key, and StoC. Looking at the previous lines, some of these values are greater than 12 bytes in length, so naturally the result will be greater than 12 bytes in length when these are added together. To solve the problem, reduce the lengths of the components, so that when they are added together, the result will be 12 bytes in length.
    – mti2935
    Commented Dec 7, 2023 at 17:59
  • 1
    There is no tag_length parameter and min_tag_length (mentioned in your text but not your code) applies only on decryption. On encryption just get the 16-byte tag and truncate it as desired (preferably consistent with SP800-38D); see the blue 'Note:' at cryptography.io/en/latest/hazmat/primitives/… . @mti2935: length of the AAD has nothing to do with length of the tag. Commented Dec 8, 2023 at 1:16

1 Answer 1

0

Technically, you can't do this. GCM is defined such that the authentication tag is a point in the Galois field GF(2^128), which requires 128 bits (16 bytes) of data to specify. In other words, the tag size isn't variable. It would technically be possible to create a variant of GCM with a smaller field, but at that point you're not just rolling your own implementation (very bad idea, especially if you need to ask questions like this), you'd be rolling your own primitive (never do that).

With that said, if for some reason you absolutely can't store/verify 16 byte values, you could potentially shorten the tag before storing it, and then perform the same shortening on the generated tag at decryption before comparing it. This would prevent using libraries that handle the verification for you, but you're already using the aptly-named hazardous materials module. You'd obviously lose some security doing this, even if your implementation had no flaws. You'd also need to consider how you want to shorten the tag. Simply truncating the last 4 bytes would technically work, but might lose you more than 1/4 of the entropy if its disproportionately in the least significant bytes rather than evenly distributed. You could try hashing the tag and then using a truncation of the digest (no secure hash function today has a digest of only 96 bits). The Cryptography SE might know better.

... It really has to be asked, though: Why? An extra four bytes per auth tag isn't going to break your database or whatever, or add undue RAM or compute burden on the process. Using a non-standard auth tag size is going to prevent using widely-implemented and well-tested libraries, forcing you to "roll your own" on top of the primitives and vastly increasing the risk of an implementation error1 that destroys the security of the system, and for what? Why the urgent need to make the authentication four billion times weaker?

1 I don't know if this is exactly an error or not, but why does your example code have hardcoded constants, such as for the nonce (IV)? That cripples the security of GCM.

2
  • NIST disagrees; SP800-38D explicitly allows truncating tag to 12 bytes, and even to 8 or 4 given certain requirements on the application and limits on the data (length and number of GMACs per key) Commented Dec 9, 2023 at 3:18
  • Presumably the construction still supplies a 128-bit tag, and you just apply some truncation function? So basically the second paragraph here, except there is apparently an official way to do it (which wasn't in the stuff I read). That's cool, I guess, though I'm stuff confused why. The savings are so small.
    – CBHacking
    Commented Dec 9, 2023 at 7:30

You must log in to answer this question.

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