Nonce That Never Moved

Ten million rows of government IDs are encrypted with this function, all under one key.

from cryptography.hazmat.primitives.ciphers.aead import AESGCM

KEY = load_key_from_kms()      # one 256-bit key for the whole table
NONCE = b"\x00" * 12          # "GCM wants 12 bytes, here they are"

def encrypt_id(plaintext: str) -> bytes:
    return AESGCM(KEY).encrypt(NONCE, plaintext.encode(), None)

What is the worst consequence of this code, assuming the key itself is never disclosed?

A

The nonce is too short. NIST requires 128-bit IVs for AES-GCM, so widening NONCE to 16 bytes resolves it.

B

Confidentiality and authenticity both collapse. Two ciphertexts under the same nonce and key XOR to the XOR of their plaintexts, and the repeated nonce also exposes GCM's authentication subkey, so an attacker can forge valid tags for ciphertexts they choose.

C

Only equality leaks. Identical IDs produce identical ciphertexts, so the scheme degrades to deterministic encryption, but the authentication tags still detect tampering.

D

Nothing while the key stays secret. GCM derives a distinct per-message subkey from the message length, so a constant nonce costs throughput and not security.