java.lang.security.audit.crypto.gcm-detection.gcm-detection

Author
221
Download Count*
License
GCM detected, please check that IV/nonce is not reused, an Initialization Vector (IV) is a nonce used to randomize the encryption, so that even if multiple messages with identical plaintext are encrypted, the generated corresponding ciphertexts are different. Unlike the Key, the IV usually does not need to be secret, rather it is important that it is random and unique. Certain encryption schemes the IV is exchanged in public as part of the ciphertext. Reusing same Initialization Vector with the same Key to encrypt multiple plaintext blocks allows an attacker to compare the ciphertexts and then, with some assumptions on the content of the messages, to gain important information about the data being encrypted.
Run Locally
Run in CI
Defintion
rules:
- id: gcm-detection
metadata:
category: security
cwe:
- "CWE-323: Reusing a Nonce, Key Pair in Encryption"
references:
- https://cwe.mitre.org/data/definitions/323.html
technology:
- java
owasp:
- A02:2021 - Cryptographic Failures
subcategory:
- vuln
likelihood: MEDIUM
impact: MEDIUM
confidence: HIGH
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- java
message: GCM detected, please check that IV/nonce is not reused, an
Initialization Vector (IV) is a nonce used to randomize the encryption, so
that even if multiple messages with identical plaintext are encrypted, the
generated corresponding ciphertexts are different. Unlike the Key, the IV
usually does not need to be secret, rather it is important that it is
random and unique. Certain encryption schemes the IV is exchanged in
public as part of the ciphertext. Reusing same Initialization Vector with
the same Key to encrypt multiple plaintext blocks allows an attacker to
compare the ciphertexts and then, with some assumptions on the content of
the messages, to gain important information about the data being
encrypted.
patterns:
- pattern-either:
- pattern: $METHOD.getInstance("AES/GCM/NoPadding",...);
- pattern: new GCMParameterSpec(...);
severity: INFO
Examples
gcm-detection.java
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class GcmHardcodedIV
{
public static final int GCM_TAG_LENGTH = 16;
public static final String BAD_IV = "ab0123456789";
public static final byte[] BAD_IV2 = new byte[]{0,1,2,3,4,5,6,7,8,9,10,11};
private static byte[] theIV;
private static SecretKey theKey;
public static void main( String[] args )
{
String clearText = args[0];
System.out.println(clearText);
try {
setKeys();
String cipherText = encrypt(clearText);
System.out.println(cipherText);
String decrypted = decrypt(cipherText);
System.out.println(decrypted);
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
public static String encrypt(String clearText) throws Exception {
// ruleid:gcm-detection
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(theKey.getEncoded(), "AES");
byte[] theBadIV = BAD_IV.getBytes();
// ruleid:gcm-detection
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, theBadIV);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
byte[] cipherText = cipher.doFinal(clearText.getBytes());
return Base64.getEncoder().encodeToString(cipherText);
}
public static String decrypt(String cipherText) throws Exception {
// ruleid:gcm-detection
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(theKey.getEncoded(), "AES");
// ruleid:gcm-detection
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, theIV);
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
byte[] decoded = Base64.getDecoder().decode(cipherText);
byte[] decryptedText = cipher.doFinal(decoded);
return new String(decryptedText);
}
public static void setKeys() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
theIV = BAD_IV.getBytes();
}
}
Short Link: https://sg.run/BLLb