{"title":"AES-CTR Nonce Reuse Leading to Keystream Recovery","language":"Python","severity":"High","cwe":"CWE-323","source_lines":[7],"flow_lines":[7,10],"sink_lines":[10],"vulnerable_code":"from Crypto.Cipher import AES\nimport os\n\nclass IoTSensorEncryptor:\n    def __init__(self):\n        self.device_key = os.urandom(32)\n        self.static_nonce = os.urandom(8)\n    \n    def transmit_telemetry(self, sensor_data):\n        cipher = AES.new(self.device_key, AES.MODE_CTR, nonce=self.static_nonce)\n        encrypted_payload = cipher.encrypt(sensor_data.encode())\n        return encrypted_payload\n    \n    def send_batch_readings(self, readings_list):\n        encrypted_batch = []\n        for reading in readings_list:\n            encrypted_batch.append(self.transmit_telemetry(reading))\n        return encrypted_batch","explanation":"The code initializes a static nonce once in __init__ (line 7) and reuses it for every encryption operation in transmit_telemetry (line 10). In AES-CTR mode, reusing the same nonce with the same key generates identical keystreams, allowing attackers to XOR multiple ciphertexts together to recover plaintext without knowing the key.","remediation":"The fix removes the static nonce from the class initialization and instead generates a fresh random nonce for each encryption operation in transmit_telemetry. The nonce is prepended to the ciphertext so the receiver can extract it for decryption. This ensures a unique keystream is produced for every message, preventing the XOR attack on multiple ciphertexts.","secure_code":"from Crypto.Cipher import AES\nimport os\n\nclass IoTSensorEncryptor:\n    def __init__(self):\n        self.device_key = os.urandom(32)\n    \n    def transmit_telemetry(self, sensor_data):\n        nonce = os.urandom(8)\n        cipher = AES.new(self.device_key, AES.MODE_CTR, nonce=nonce)\n        encrypted_payload = cipher.encrypt(sensor_data.encode())\n        return nonce + encrypted_payload\n    \n    def send_batch_readings(self, readings_list):\n        encrypted_batch = []\n        for reading in readings_list:\n            encrypted_batch.append(self.transmit_telemetry(reading))\n        return encrypted_batch"}