Files
codeql/java/ql/test/experimental/library-tests/quantum/jca/Nonce.java
2025-10-06 10:46:09 -04:00

115 lines
3.8 KiB
Java

package com.example.crypto.artifacts;
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.Cipher;
import java.security.*;
import java.util.Base64;
import java.util.Random;
public class Nonce {
// static {
// Security.addProvider(new BouncyCastleProvider()); // Ensure BouncyCastle is available
// }
/**
* Simple Case: Generates a secure nonce and uses it in HMAC.
*/
public void simpleNonceUsage() throws Exception {
byte[] nonce = secureNonce(16);
SecretKey key = generateHmacKey();
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(key);
mac.update(nonce);
byte[] macResult = mac.doFinal("Simple Test Data".getBytes());
}
/**
* Incorrect: Hardcoded, reused nonce in encryption, leading to predictable
* output.
*/
public void hardcodedNonceReuse() throws Exception {
byte[] nonce = "BADNONCEBADNONCE".getBytes(); // HARDCODED NONCE REUSED!
SecretKey key = generateHmacKey();
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(key);
mac.update(nonce);
byte[] macResult = mac.doFinal("Sensitive Data".getBytes());
}
/**
* Incorrect: Reusing a nonce with AES-GCM, which can lead to catastrophic
* security failures.
*/
public void insecureNonceReuseGCM(SecretKey key, byte[] plaintext) throws Exception {
byte[] nonce = getReusedNonce(12); // SAME NONCE REUSED!
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, nonce);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, gcmSpec);
byte[] ciphertext = cipher.doFinal(plaintext);
}
/**
* Secure Case: Proper unique nonce usage in AES-GCM.
*/
public void secureNonceUsageGCM(SecretKey key, byte[] plaintext) throws Exception {
byte[] nonce = secureNonce(12);
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, nonce);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, gcmSpec);
byte[] ciphertext = cipher.doFinal(plaintext);
}
public void complexNonceFlow() {
byte[] nonce = useSecureMethod() ? secureNonce(16) : insecureNonce(16);
processNonce(nonce);
try {
useNonceInMac(nonce, generateHmacKey(), "HmacSHA256");
} catch (Exception e) {
e.printStackTrace();
}
}
public void useNonceInMac(byte[] nonce, SecretKey key, String macAlgorithm) throws Exception {
Mac mac = Mac.getInstance(macAlgorithm);
mac.init(key);
mac.update(nonce);
byte[] macResult = mac.doFinal("Sensitive Data".getBytes());
}
private boolean useSecureMethod() {
return System.currentTimeMillis() % 2 == 0;
}
private void processNonce(byte[] nonce) {
String nonceBase64 = Base64.getEncoder().encodeToString(nonce);
}
private SecretKey generateHmacKey() throws NoSuchAlgorithmException {
KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");
return keyGen.generateKey();
}
private byte[] secureNonce(int length) {
byte[] nonce = new byte[length];
new SecureRandom().nextBytes(nonce);
return nonce;
}
private byte[] insecureNonce(int length) {
byte[] nonce = new byte[length];
new Random().nextBytes(nonce);
return nonce;
}
/**
* Incorrect: A nonce that is stored and reused across multiple encryptions.
*/
private byte[] getReusedNonce(int length) {
return "BADNONCEBADNONCE".getBytes(); // Fixed nonce reuse across calls
}
}