When encrypting data with Counter (CTR) derived block cipher modes of operation, it is essential not to reuse the same initialization vector (IV)
with a given key, such IV is called a "nonce" (number used only once). Galois/Counter (GCM) and Counter with Cipher Block Chaining-Message
Authentication Code (CCM) are both CTR-based modes of operation.
An attacker, who has knowledge of one plaintext (original content) and ciphertext (encrypted content) pair, is able to retrieve the corresponding
plaintext of any other ciphertext generated with the same IV and key. It also drastically decreases the key recovery computational complexity by
downgrading it to a simpler polynomial root-finding problem.
When using GCM, NIST recommends a 96 bit length nonce using a 'Deterministic' approach or at least 96 bits using a 'Random Bit Generator (RBG)'.
The 'Deterministic' construction involves a counter, which increments per encryption process. The 'RBG' construction, as the name suggests, generates
the nonce using a random bit generator. Collision probabilities (nonce-key pair reuse) using the 'RBG-based' approach require a shorter key rotation
period, 2^32 maximum invocations per key.
Noncompliant Code Example
public void encrypt(byte[] key, byte[] ptxt) {
byte[] bytesIV = "7cVgr5cbdCZV".getBytes("UTF-8"); // The initialization vector is a static value
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, nonce); // The initialization vector is configured here
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); // Noncompliant
}
Compliant Solution
public void encrypt(byte[] key, byte[] ptxt) {
SecureRandom random = new SecureRandom();
byte[] bytesIV = new byte[12];
random.nextBytes(bytesIV); // Random 96 bit IV
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, nonce);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
}
See