{"title":"AES-GCM Nonce Reuse Leading to Keystream Recovery","language":"Python","severity":"Critical","cwe":"CWE-323","source_lines":[7],"flow_lines":[7,10,13],"sink_lines":[10],"vulnerable_code":"from cryptography.hazmat.primitives.ciphers.aead import AESGCM\nimport os\n\nclass IoTSensorEncryptor:\n    def __init__(self, master_key):\n        self.cipher = AESGCM(master_key)\n        self.device_nonce = os.urandom(12)\n    \n    def encrypt_telemetry(self, sensor_data, device_id):\n        encrypted = self.cipher.encrypt(self.device_nonce, sensor_data.encode(), device_id.encode())\n        return encrypted.hex()\n    \n    def batch_encrypt_readings(self, readings_list, device_id):\n        return [self.encrypt_telemetry(reading, device_id) for reading in readings_list]","explanation":"The nonce (self.device_nonce) is generated once in __init__ and reused across multiple encrypt_telemetry calls. In AES-GCM, nonce reuse with the same key allows attackers to XOR two ciphertexts encrypted with the same nonce to recover keystream material, compromising confidentiality and authenticity of all encrypted messages.","remediation":"The fix generates a fresh random 12-byte nonce for every encryption operation instead of reusing a single nonce stored as an instance variable. The nonce is prepended to the ciphertext so the decryptor can extract it for decryption. This ensures that no two encryptions ever share the same nonce, preventing keystream recovery attacks.","secure_code":"from cryptography.hazmat.primitives.ciphers.aead import AESGCM\nimport os\n\nclass IoTSensorEncryptor:\n    def __init__(self, master_key):\n        self.cipher = AESGCM(master_key)\n    \n    def encrypt_telemetry(self, sensor_data, device_id):\n        nonce = os.urandom(12)\n        encrypted = self.cipher.encrypt(nonce, sensor_data.encode(), device_id.encode())\n        return (nonce + encrypted).hex()\n    \n    def batch_encrypt_readings(self, readings_list, device_id):\n        return [self.encrypt_telemetry(reading, device_id) for reading in readings_list]"}