mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
115 lines
3.8 KiB
Java
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
|
|
}
|
|
}
|