CodeQL documentation

Using a static initialization vector for encryption

ID: java/static-initialization-vector Kind: path-problem Security severity: 7.5 Severity: warning Precision: high Tags: - security - external/cwe/cwe-329 - external/cwe/cwe-1204 Query suites: - java-code-scanning.qls - java-security-extended.qls - java-security-and-quality.qls 

Click to see the query in the CodeQL repository

When a cipher is used in certain modes such as CBC or GCM, it requires an initialization vector (IV). Under the same secret key, IVs should be unique and ideally unpredictable. If the same IV is used with the same secret key, then the same plaintext results in the same ciphertext. This can let an attacker learn if the same data pieces are transferred or stored, or help the attacker run a dictionary attack.

Recommendation

Use a random IV generated by SecureRandom.

Example

The following example initializes a cipher with a static IV, which is unsafe:

byte[] iv = new byte[16]; // BAD: all zeroes GCMParameterSpec params = new GCMParameterSpec(128, iv); Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING"); cipher.init(Cipher.ENCRYPT_MODE, key, params); 

The next example initializes a cipher with a random IV:

byte[] iv = new byte[16]; SecureRandom random = SecureRandom.getInstanceStrong(); random.nextBytes(iv); // GOOD: random initialization vector GCMParameterSpec params = new GCMParameterSpec(128, iv); Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING"); cipher.init(Cipher.ENCRYPT_MODE, key, params); 

References