mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Crypto: Formatting test cases, more removal of non-ascii
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.security.*;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
@@ -20,29 +19,23 @@ import java.util.Base64;
|
||||
*
|
||||
* This file includes:
|
||||
*
|
||||
* 1. AESWrap Examples:
|
||||
* - secureAESWrap(): Uses a randomly generated wrapping key.
|
||||
* - insecureAESWrap(): Uses a fixed, hard-coded wrapping key.
|
||||
* 1. AESWrap Examples: - secureAESWrap(): Uses a randomly generated wrapping
|
||||
* key. - insecureAESWrap(): Uses a fixed, hard-coded wrapping key.
|
||||
*
|
||||
* 2. PBEWith Examples:
|
||||
* - insecurePBEExample(): Uses the legacy PBEWithMD5AndDES.
|
||||
* - securePBEExample(): Uses PBKDF2WithHmacSHA256.
|
||||
* - additionalPBEExample(): Uses PBEWithSHA256And128BitAES-CBC-BC.
|
||||
* - additionalPBEExample2(): Uses PBEWithSHA1And128BitAES-CBC-BC.
|
||||
* 2. PBEWith Examples: - insecurePBEExample(): Uses the legacy
|
||||
* PBEWithMD5AndDES. - securePBEExample(): Uses PBKDF2WithHmacSHA256. -
|
||||
* additionalPBEExample(): Uses PBEWithSHA256And128BitAES-CBC-BC. -
|
||||
* additionalPBEExample2(): Uses PBEWithSHA1And128BitAES-CBC-BC.
|
||||
*
|
||||
* 3. Dynamic PBE Encryption:
|
||||
* - dynamicPBEEncryption(): Chooses the PBE transformation based on a
|
||||
* configuration string.
|
||||
* 3. Dynamic PBE Encryption: - dynamicPBEEncryption(): Chooses the PBE
|
||||
* transformation based on a configuration string.
|
||||
*
|
||||
* Best Practices:
|
||||
* - Use secure random keys and salts.
|
||||
* - Avoid legacy algorithms like PBEWithMD5AndDES.
|
||||
* - Prefer modern KDFs (PBKDF2WithHmacSHA256) and secure provider-specific PBE
|
||||
* transformations.
|
||||
* Best Practices: - Use secure random keys and salts. - Avoid legacy algorithms
|
||||
* like PBEWithMD5AndDES. - Prefer modern KDFs (PBKDF2WithHmacSHA256) and secure
|
||||
* provider-specific PBE transformations.
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - Insecure examples (PBEWithMD5AndDES, fixed keys) should be flagged.
|
||||
* - Secure examples use random salt, high iteration counts, and strong
|
||||
* SAST/CBOM Notes: - Insecure examples (PBEWithMD5AndDES, fixed keys) should be
|
||||
* flagged. - Secure examples use random salt, high iteration counts, and strong
|
||||
* algorithms.
|
||||
*/
|
||||
public class AesWrapAndPBEWith {
|
||||
@@ -51,14 +44,12 @@ public class AesWrapAndPBEWith {
|
||||
// // Register BouncyCastle as a provider.
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
// ===========================
|
||||
// 1. AESWrap Examples
|
||||
// ===========================
|
||||
|
||||
/**
|
||||
* Secure AES key wrapping.
|
||||
* Generates a random 256-bit wrapping key to wrap a target AES key.
|
||||
* Secure AES key wrapping. Generates a random 256-bit wrapping key to wrap
|
||||
* a target AES key.
|
||||
*
|
||||
* @return The wrapped key (Base64-encoded).
|
||||
* @throws Exception if an error occurs.
|
||||
@@ -79,8 +70,7 @@ public class AesWrapAndPBEWith {
|
||||
}
|
||||
|
||||
/**
|
||||
* Insecure AES key wrapping.
|
||||
* Uses a fixed (hard-coded) wrapping key.
|
||||
* Insecure AES key wrapping. Uses a fixed (hard-coded) wrapping key.
|
||||
*
|
||||
* @return The wrapped key (Base64-encoded).
|
||||
* @throws Exception if an error occurs.
|
||||
@@ -104,7 +94,6 @@ public class AesWrapAndPBEWith {
|
||||
// ===========================
|
||||
// 2. PBEWith Examples
|
||||
// ===========================
|
||||
|
||||
/**
|
||||
* Insecure PBE example using PBEWithMD5AndDES.
|
||||
*
|
||||
@@ -141,7 +130,7 @@ public class AesWrapAndPBEWith {
|
||||
/**
|
||||
* Additional PBE example using PBEWithSHA256And128BitAES-CBC-BC.
|
||||
*
|
||||
* @param password The input password.
|
||||
* @param password The input password.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The IV concatenated with ciphertext (Base64-encoded).
|
||||
* @throws Exception if key derivation or encryption fails.
|
||||
@@ -165,11 +154,10 @@ public class AesWrapAndPBEWith {
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional PBE example using PBEWithSHA1And128BitAES-CBC-BC.
|
||||
* This is less preferred than PBKDF2WithHmacSHA256 but demonstrates another
|
||||
* variant.
|
||||
* Additional PBE example using PBEWithSHA1And128BitAES-CBC-BC. This is less
|
||||
* preferred than PBKDF2WithHmacSHA256 but demonstrates another variant.
|
||||
*
|
||||
* @param password The input password.
|
||||
* @param password The input password.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The IV concatenated with ciphertext (Base64-encoded).
|
||||
* @throws Exception if key derivation or encryption fails.
|
||||
@@ -195,18 +183,16 @@ public class AesWrapAndPBEWith {
|
||||
// ===========================
|
||||
// 3. Dynamic PBE Encryption
|
||||
// ===========================
|
||||
|
||||
/**
|
||||
* Dynamically selects a PBE transformation based on a configuration string.
|
||||
*
|
||||
* Acceptable values:
|
||||
* - "PBKDF2": Uses PBKDF2WithHmacSHA256.
|
||||
* - "SHA256AES": Uses PBEWithSHA256And128BitAES-CBC-BC.
|
||||
* - "SHA1AES": Uses PBEWithSHA1And128BitAES-CBC-BC.
|
||||
* - Otherwise, falls back to insecure PBEWithMD5AndDES.
|
||||
* Acceptable values: - "PBKDF2": Uses PBKDF2WithHmacSHA256. - "SHA256AES":
|
||||
* Uses PBEWithSHA256And128BitAES-CBC-BC. - "SHA1AES": Uses
|
||||
* PBEWithSHA1And128BitAES-CBC-BC. - Otherwise, falls back to insecure
|
||||
* PBEWithMD5AndDES.
|
||||
*
|
||||
* @param config The configuration string.
|
||||
* @param password The input password.
|
||||
* @param config The configuration string.
|
||||
* @param password The input password.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The Base64-encoded encrypted output.
|
||||
* @throws Exception if an error occurs.
|
||||
@@ -227,7 +213,6 @@ public class AesWrapAndPBEWith {
|
||||
// ===========================
|
||||
// Helper Methods
|
||||
// ===========================
|
||||
|
||||
/**
|
||||
* Concatenates two byte arrays.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,10 @@ package com.example.crypto.algorithms;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
// import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyAgreement;
|
||||
import javax.crypto.KeyGenerator;
|
||||
@@ -10,42 +13,31 @@ import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* AsymmetricEncryptionMacHybridCryptosystem demonstrates hybrid
|
||||
* cryptosystems that combine asymmetric encryption with a MAC.
|
||||
* AsymmetricEncryptionMacHybridCryptosystem demonstrates hybrid cryptosystems
|
||||
* that combine asymmetric encryption with a MAC.
|
||||
*
|
||||
* Flows:
|
||||
* 1. RSA-OAEP + HMAC:
|
||||
* - Secure Flow: Uses 2048-bit RSA-OAEP (with SHA256andMGF1Padding) to
|
||||
* encapsulate a freshly generated AES key;
|
||||
* then encrypts using AES-GCM with a random nonce and computes HMAC-SHA256 over
|
||||
* the ciphertext.
|
||||
* - Insecure Flow: Uses 1024-bit RSA (RSA/ECB/PKCS1Padding), AES-GCM with a
|
||||
* fixed IV, and HMAC-SHA1.
|
||||
* Flows: 1. RSA-OAEP + HMAC: - Secure Flow: Uses 2048-bit RSA-OAEP (with
|
||||
* SHA256andMGF1Padding) to encapsulate a freshly generated AES key; then
|
||||
* encrypts using AES-GCM with a random nonce and computes HMAC-SHA256 over the
|
||||
* ciphertext. - Insecure Flow: Uses 1024-bit RSA (RSA/ECB/PKCS1Padding),
|
||||
* AES-GCM with a fixed IV, and HMAC-SHA1.
|
||||
*
|
||||
* 2. ECIES + HMAC:
|
||||
* - Secure Flow: Uses ephemeral ECDH key pairs (secp256r1); derives a shared
|
||||
* secret and applies a simple KDF (SHA-256)
|
||||
* to derive a 128-bit AES key; then uses AES-GCM with a random nonce and
|
||||
* computes HMAC-SHA256.
|
||||
* - Insecure Flow: Reuses a static EC key pair, directly truncates the shared
|
||||
* secret without a proper KDF,
|
||||
* uses a fixed IV, and computes HMAC-SHA1.
|
||||
* 2. ECIES + HMAC: - Secure Flow: Uses ephemeral ECDH key pairs (secp256r1);
|
||||
* derives a shared secret and applies a simple KDF (SHA-256) to derive a
|
||||
* 128-bit AES key; then uses AES-GCM with a random nonce and computes
|
||||
* HMAC-SHA256. - Insecure Flow: Reuses a static EC key pair, directly truncates
|
||||
* the shared secret without a proper KDF, uses a fixed IV, and computes
|
||||
* HMAC-SHA1.
|
||||
*
|
||||
* 3. Dynamic Hybrid Selection:
|
||||
* - Chooses between flows based on a configuration string.
|
||||
* 3. Dynamic Hybrid Selection: - Chooses between flows based on a configuration
|
||||
* string.
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - Secure flows use proper ephemeral key generation, secure key sizes, KDF
|
||||
* usage, and random nonces/IVs.
|
||||
* - Insecure flows (static key reuse, fixed nonces, weak key sizes, raw shared
|
||||
* secret truncation, and deprecated algorithms)
|
||||
* should be flagged.
|
||||
* SAST/CBOM Notes: - Secure flows use proper ephemeral key generation, secure
|
||||
* key sizes, KDF usage, and random nonces/IVs. - Insecure flows (static key
|
||||
* reuse, fixed nonces, weak key sizes, raw shared secret truncation, and
|
||||
* deprecated algorithms) should be flagged.
|
||||
*/
|
||||
public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
|
||||
@@ -53,9 +45,9 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// Security.addProvider(new BouncyCastlePQCProvider());
|
||||
// }
|
||||
|
||||
// ---------- Result Class ----------
|
||||
public static class HybridResult {
|
||||
|
||||
private final byte[] encapsulatedKey;
|
||||
private final byte[] ciphertext;
|
||||
private final byte[] mac;
|
||||
@@ -79,14 +71,13 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
}
|
||||
|
||||
public String toBase64String() {
|
||||
return "EncapsulatedKey: " + Base64.getEncoder().encodeToString(encapsulatedKey) +
|
||||
"\nCiphertext: " + Base64.getEncoder().encodeToString(ciphertext) +
|
||||
"\nMAC: " + Base64.getEncoder().encodeToString(mac);
|
||||
return "EncapsulatedKey: " + Base64.getEncoder().encodeToString(encapsulatedKey)
|
||||
+ "\nCiphertext: " + Base64.getEncoder().encodeToString(ciphertext)
|
||||
+ "\nMAC: " + Base64.getEncoder().encodeToString(mac);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Helper Methods ----------
|
||||
|
||||
/**
|
||||
* Generates an ephemeral ECDH key pair on secp256r1.
|
||||
*/
|
||||
@@ -107,10 +98,10 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
|
||||
/**
|
||||
* Derives a shared secret using the provided key agreement algorithm.
|
||||
*
|
||||
*
|
||||
* @param privateKey The private key.
|
||||
* @param publicKey The corresponding public key.
|
||||
* @param algorithm The key agreement algorithm (e.g., "ECDH" or "X25519").
|
||||
* @param publicKey The corresponding public key.
|
||||
* @param algorithm The key agreement algorithm (e.g., "ECDH" or "X25519").
|
||||
* @return The shared secret.
|
||||
*/
|
||||
public byte[] deriveSharedSecret(PrivateKey privateKey, PublicKey publicKey, String algorithm) throws Exception {
|
||||
@@ -123,8 +114,8 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
/**
|
||||
* A simple KDF that hashes the input with SHA-256 and returns the first
|
||||
* numBytes.
|
||||
*
|
||||
* @param input The input byte array.
|
||||
*
|
||||
* @param input The input byte array.
|
||||
* @param numBytes The desired number of output bytes.
|
||||
* @return The derived key material.
|
||||
*/
|
||||
@@ -147,7 +138,6 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
// =====================================================
|
||||
// 1. RSA-OAEP + HMAC Hybrid Cryptosystem
|
||||
// =====================================================
|
||||
|
||||
/**
|
||||
* Generates a secure 2048-bit RSA key pair.
|
||||
*/
|
||||
@@ -216,7 +206,6 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
// =====================================================
|
||||
// 2. ECIES + HMAC Hybrid Cryptosystem
|
||||
// =====================================================
|
||||
|
||||
/**
|
||||
* Secure hybrid encryption using ECIES (via ECDH) + HMAC-SHA256.
|
||||
*/
|
||||
@@ -268,16 +257,15 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
// =====================================================
|
||||
// 3. Dynamic Hybrid Selection
|
||||
// =====================================================
|
||||
|
||||
/**
|
||||
* Dynamically selects a hybrid encryption flow based on configuration.
|
||||
* SAST: Dynamic selection introduces risk if insecure defaults are chosen.
|
||||
*
|
||||
* @param config The configuration string ("secureRSA", "insecureRSA",
|
||||
* "secureECIES", "insecureECIES").
|
||||
* @param config The configuration string ("secureRSA", "insecureRSA",
|
||||
* "secureECIES", "insecureECIES").
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return A Base64-encoded string representation of the hybrid encryption
|
||||
* result.
|
||||
* result.
|
||||
* @throws Exception if an error occurs.
|
||||
*/
|
||||
public String dynamicHybridEncryption(String config, byte[] plaintext) throws Exception {
|
||||
@@ -300,10 +288,8 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
// =====================================================
|
||||
// 4. Helper Methods for HMAC and Symmetric Encryption
|
||||
// =====================================================
|
||||
|
||||
/**
|
||||
* Secure HMAC using HMAC-SHA256.
|
||||
* SAST: HMAC-SHA256 is secure.
|
||||
* Secure HMAC using HMAC-SHA256. SAST: HMAC-SHA256 is secure.
|
||||
*/
|
||||
public byte[] secureHMACSHA256(String message, byte[] key) throws Exception {
|
||||
Mac mac = Mac.getInstance("HmacSHA256", "BC");
|
||||
@@ -313,8 +299,8 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
}
|
||||
|
||||
/**
|
||||
* Insecure HMAC using HMAC-SHA1.
|
||||
* SAST: HMAC-SHA1 is deprecated and insecure.
|
||||
* Insecure HMAC using HMAC-SHA1. SAST: HMAC-SHA1 is deprecated and
|
||||
* insecure.
|
||||
*/
|
||||
public byte[] insecureHMACSHA1(String message, byte[] key) throws Exception {
|
||||
Mac mac = Mac.getInstance("HmacSHA1", "BC");
|
||||
@@ -326,10 +312,9 @@ public class AsymmetricEncryptionMacHybridCryptosystem {
|
||||
// =====================================================
|
||||
// 5. Helper Methods for Key/Nonce Generation
|
||||
// =====================================================
|
||||
|
||||
/**
|
||||
* Generates a secure 256-bit AES key.
|
||||
* SAST: Uses SecureRandom for key generation.
|
||||
* Generates a secure 256-bit AES key. SAST: Uses SecureRandom for key
|
||||
* generation.
|
||||
*/
|
||||
public SecretKey generateAESKey() throws Exception {
|
||||
KeyGenerator kg = KeyGenerator.getInstance("AES");
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.security.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
||||
public class ChainedEncryptionTest {
|
||||
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
// Encrypts using AES-GCM. Returns IV concatenated with ciphertext.
|
||||
public static byte[] encryptAESGCM(SecretKey key, byte[] plaintext) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
@@ -68,10 +63,10 @@ public class ChainedEncryptionTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs chained encryption and decryption in one function.
|
||||
* First, plaintext is encrypted with AES-GCM (inner layer),
|
||||
* then that ciphertext is encrypted with ChaCha20-Poly1305 (outer layer).
|
||||
* The decryption process reverses these steps.
|
||||
* Performs chained encryption and decryption in one function. First,
|
||||
* plaintext is encrypted with AES-GCM (inner layer), then that ciphertext
|
||||
* is encrypted with ChaCha20-Poly1305 (outer layer). The decryption process
|
||||
* reverses these steps.
|
||||
*
|
||||
* @param plaintext The input plaintext.
|
||||
* @return The decrypted plaintext as a String.
|
||||
@@ -148,4 +143,4 @@ public class ChainedEncryptionTest {
|
||||
System.out.println("Decrypted: " + new String(decryptedPlaintext));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,18 @@ package com.example.crypto.artifacts;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.security.*;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* DigestTestCase demonstrates the further use of cryptographic digests
|
||||
|
||||
@@ -4,7 +4,6 @@ package com.example.crypto.algorithms;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.Security;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,40 +1,33 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyAgreement;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* EllipticCurve2 demonstrates real-world uses of elliptic curve algorithms,
|
||||
* including key pair generation, key agreement (ECDH), digital signatures
|
||||
* (ECDSA, EdDSA),
|
||||
* and a simple simulation of ECIES (using ECDH + AES-GCM).
|
||||
* (ECDSA, EdDSA), and a simple simulation of ECIES (using ECDH + AES-GCM).
|
||||
*
|
||||
* Curve types shown include:
|
||||
* - NIST (e.g., secp256r1)
|
||||
* - SEC (e.g., secp256k1)
|
||||
* - Brainpool (e.g., brainpoolP256r1)
|
||||
* - CURVE25519 (for X25519 key agreement)
|
||||
* - ES (e.g., Ed25519 for signatures)
|
||||
* - Other fallback (e.g., secp256r1 for "OtherEllipticCurveType")
|
||||
* Curve types shown include: - NIST (e.g., secp256r1) - SEC (e.g., secp256k1) -
|
||||
* Brainpool (e.g., brainpoolP256r1) - CURVE25519 (for X25519 key agreement) -
|
||||
* ES (e.g., Ed25519 for signatures) - Other fallback (e.g., secp256r1 for
|
||||
* "OtherEllipticCurveType")
|
||||
*
|
||||
* Best practices:
|
||||
* - Use ephemeral keys and a strong RNG.
|
||||
* - Use proper key agreement (with a KDF if needed) and digital signature
|
||||
* schemes.
|
||||
* - Avoid static key reuse or using weak curves.
|
||||
* Best practices: - Use ephemeral keys and a strong RNG. - Use proper key
|
||||
* agreement (with a KDF if needed) and digital signature schemes. - Avoid
|
||||
* static key reuse or using weak curves.
|
||||
*
|
||||
* SAST/CBOM considerations:
|
||||
* - Secure implementations use ephemeral keys and modern curves.
|
||||
* - Insecure practices (e.g., static keys or reusing keys) must be flagged.
|
||||
* SAST/CBOM considerations: - Secure implementations use ephemeral keys and
|
||||
* modern curves. - Insecure practices (e.g., static keys or reusing keys) must
|
||||
* be flagged.
|
||||
*/
|
||||
public class EllipticCurve2 {
|
||||
|
||||
@@ -42,11 +35,9 @@ public class EllipticCurve2 {
|
||||
// // Register BouncyCastle provider for additional curves and algorithms.
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
// ----------------------------
|
||||
// 1. Key Pair Generation Examples
|
||||
// ----------------------------
|
||||
|
||||
/**
|
||||
* Generates a key pair using a NIST curve (secp256r1).
|
||||
*/
|
||||
@@ -101,10 +92,9 @@ public class EllipticCurve2 {
|
||||
// ----------------------------
|
||||
// 2. Key Agreement (ECDH) Examples
|
||||
// ----------------------------
|
||||
|
||||
/**
|
||||
* Performs ECDH key agreement using two ephemeral NIST key pairs.
|
||||
* Secure Example: Uses ephemeral keys and a strong RNG.
|
||||
* Performs ECDH key agreement using two ephemeral NIST key pairs. Secure
|
||||
* Example: Uses ephemeral keys and a strong RNG.
|
||||
*
|
||||
* @return The shared secret.
|
||||
*/
|
||||
@@ -119,8 +109,8 @@ public class EllipticCurve2 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Insecure ECDH Example: Uses a static key pair for both parties.
|
||||
* SAST: Reusing the same key pair eliminates forward secrecy and is insecure.
|
||||
* Insecure ECDH Example: Uses a static key pair for both parties. SAST:
|
||||
* Reusing the same key pair eliminates forward secrecy and is insecure.
|
||||
*
|
||||
* @return The (insecure) shared secret.
|
||||
*/
|
||||
@@ -135,10 +125,8 @@ public class EllipticCurve2 {
|
||||
// ----------------------------
|
||||
// 3. Digital Signature Examples
|
||||
// ----------------------------
|
||||
|
||||
/**
|
||||
* Generates an ECDSA signature using a NIST key pair.
|
||||
* Secure Example.
|
||||
* Generates an ECDSA signature using a NIST key pair. Secure Example.
|
||||
*
|
||||
* @param message The message to sign.
|
||||
* @return The signature.
|
||||
@@ -154,9 +142,9 @@ public class EllipticCurve2 {
|
||||
/**
|
||||
* Verifies an ECDSA signature using the corresponding NIST key pair.
|
||||
*
|
||||
* @param message The original message.
|
||||
* @param message The original message.
|
||||
* @param signatureBytes The signature to verify.
|
||||
* @param kp The key pair used for signing.
|
||||
* @param kp The key pair used for signing.
|
||||
* @return True if the signature is valid.
|
||||
*/
|
||||
public boolean verifyECDSASignature(byte[] message, byte[] signatureBytes, KeyPair kp) throws Exception {
|
||||
@@ -167,8 +155,8 @@ public class EllipticCurve2 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an Ed25519 signature.
|
||||
* Secure Example: Ed25519 is a modern, high-performance signature scheme.
|
||||
* Generates an Ed25519 signature. Secure Example: Ed25519 is a modern,
|
||||
* high-performance signature scheme.
|
||||
*
|
||||
* @param message The message to sign.
|
||||
* @return The signature.
|
||||
@@ -184,9 +172,9 @@ public class EllipticCurve2 {
|
||||
/**
|
||||
* Verifies an Ed25519 signature.
|
||||
*
|
||||
* @param message The original message.
|
||||
* @param message The original message.
|
||||
* @param signatureBytes The signature to verify.
|
||||
* @param kp The key pair used for signing.
|
||||
* @param kp The key pair used for signing.
|
||||
* @return True if the signature is valid.
|
||||
*/
|
||||
public boolean verifyEd25519Signature(byte[] message, byte[] signatureBytes, KeyPair kp) throws Exception {
|
||||
@@ -199,17 +187,14 @@ public class EllipticCurve2 {
|
||||
// ----------------------------
|
||||
// 4. ECIES-like Encryption (ECDH + AES-GCM)
|
||||
// ----------------------------
|
||||
|
||||
/**
|
||||
* A simple simulation of ECIES using ECDH for key agreement and AES-GCM for
|
||||
* encryption.
|
||||
* Secure Example: Uses ephemeral ECDH key pairs, a KDF to derive a symmetric
|
||||
* key,
|
||||
* and AES-GCM with a random nonce.
|
||||
* encryption. Secure Example: Uses ephemeral ECDH key pairs, a KDF to
|
||||
* derive a symmetric key, and AES-GCM with a random nonce.
|
||||
*
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The concatenation of the ephemeral public key, IV, and ciphertext
|
||||
* (Base64-encoded).
|
||||
* (Base64-encoded).
|
||||
* @throws Exception if encryption fails.
|
||||
*/
|
||||
public String eciesEncryptionExample(byte[] plaintext) throws Exception {
|
||||
@@ -248,7 +233,6 @@ public class EllipticCurve2 {
|
||||
// ----------------------------
|
||||
// 5. Main Method for Demonstration
|
||||
// ----------------------------
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
EllipticCurve2 test = new EllipticCurve2();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import java.security.*;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import java.security.*;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* This class demonstrates several encryption schemes along with SAST/CBOM
|
||||
|
||||
@@ -1,60 +1,52 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyAgreement;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Base64;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Mac;
|
||||
|
||||
/**
|
||||
* This class demonstrates encryption schemes using elliptic-curve
|
||||
* Diffie-Hellman (ECDH)
|
||||
* and hybrid encryption methods, including a post-quantum hybrid scheme.
|
||||
* Diffie-Hellman (ECDH) and hybrid encryption methods, including a post-quantum
|
||||
* hybrid scheme.
|
||||
*
|
||||
* SAST/CBOM Classification:
|
||||
*
|
||||
* 1. EC Key Generation & ECDH Key Agreement:
|
||||
* - Parent Classification: Asymmetric Key Generation / Key Agreement.
|
||||
* - SAST: Secure when using established curves (secp256r1) and reputable
|
||||
* providers (BouncyCastle).
|
||||
*
|
||||
* 2. ECDH Hybrid Encryption:
|
||||
* - Parent Classification: Hybrid Cryptosystem (ECDH + AEAD).
|
||||
* - SAST: Uses ECDH for key agreement and AES/GCM for encryption. However, the
|
||||
* derivation of an AES key
|
||||
* by applying a single SHA-256 hash to the shared secret may be flagged as a
|
||||
* weak key derivation method.
|
||||
* A dedicated KDF (e.g., HKDF) is recommended.
|
||||
* 1. EC Key Generation & ECDH Key Agreement: - Parent Classification:
|
||||
* Asymmetric Key Generation / Key Agreement. - SAST: Secure when using
|
||||
* established curves (secp256r1) and reputable providers (BouncyCastle).
|
||||
*
|
||||
* 3. Post-Quantum Hybrid Encryption:
|
||||
* - Parent Classification: Hybrid Cryptosystem (Classical ECDH + Post-Quantum
|
||||
* Secret + KDF + AEAD).
|
||||
* - SAST: Combining classical and post-quantum components is advanced and
|
||||
* secure if implemented properly.
|
||||
* The custom HKDF expand function provided here is simplistic and may be
|
||||
* flagged in a CBOM analysis;
|
||||
* a standard HKDF library should be used in production.
|
||||
* 2. ECDH Hybrid Encryption: - Parent Classification: Hybrid Cryptosystem (ECDH
|
||||
* + AEAD). - SAST: Uses ECDH for key agreement and AES/GCM for encryption.
|
||||
* However, the derivation of an AES key by applying a single SHA-256 hash to
|
||||
* the shared secret may be flagged as a weak key derivation method. A dedicated
|
||||
* KDF (e.g., HKDF) is recommended.
|
||||
*
|
||||
* 3. Post-Quantum Hybrid Encryption: - Parent Classification: Hybrid
|
||||
* Cryptosystem (Classical ECDH + Post-Quantum Secret + KDF + AEAD). - SAST:
|
||||
* Combining classical and post-quantum components is advanced and secure if
|
||||
* implemented properly. The custom HKDF expand function provided here is
|
||||
* simplistic and may be flagged in a CBOM analysis; a standard HKDF library
|
||||
* should be used in production.
|
||||
*/
|
||||
public class Encryption2 {
|
||||
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
/**
|
||||
* Generates an Elliptic Curve (EC) key pair using the secp256r1 curve.
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - Algorithm: EC key pair generation.
|
||||
* - Parent Classification: Asymmetric Key Generation.
|
||||
* - SAST: Considered secure when using strong randomness and a reputable
|
||||
* provider.
|
||||
* SAST/CBOM Notes: - Algorithm: EC key pair generation. - Parent
|
||||
* Classification: Asymmetric Key Generation. - SAST: Considered secure when
|
||||
* using strong randomness and a reputable provider.
|
||||
*
|
||||
* @return an EC KeyPair.
|
||||
*/
|
||||
@@ -67,13 +59,12 @@ public class Encryption2 {
|
||||
/**
|
||||
* Derives a shared secret using Elliptic Curve Diffie-Hellman (ECDH).
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - Algorithm: ECDH key agreement.
|
||||
* - Parent Classification: Asymmetric Key Agreement.
|
||||
* - SAST: Secure when both parties use strong EC keys and proper randomness.
|
||||
* SAST/CBOM Notes: - Algorithm: ECDH key agreement. - Parent
|
||||
* Classification: Asymmetric Key Agreement. - SAST: Secure when both
|
||||
* parties use strong EC keys and proper randomness.
|
||||
*
|
||||
* @param privateKey the private key of one party.
|
||||
* @param publicKey the public key of the other party.
|
||||
* @param publicKey the public key of the other party.
|
||||
* @return the derived shared secret as a byte array.
|
||||
*/
|
||||
public byte[] deriveSharedSecret(PrivateKey privateKey, PublicKey publicKey) throws Exception {
|
||||
@@ -84,21 +75,17 @@ public class Encryption2 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs hybrid encryption using ECDH to derive a shared secret, then derives
|
||||
* an AES key
|
||||
* by hashing the shared secret with SHA-256, and finally encrypts the data with
|
||||
* AES-GCM.
|
||||
* Performs hybrid encryption using ECDH to derive a shared secret, then
|
||||
* derives an AES key by hashing the shared secret with SHA-256, and finally
|
||||
* encrypts the data with AES-GCM.
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - Parent Classification: Hybrid Cryptosystem (ECDH + AES-GCM).
|
||||
* - SAST: While ECDH and AES-GCM are secure, the key derivation method here (a
|
||||
* single SHA-256 hash)
|
||||
* is not as robust as using a dedicated KDF. This approach may be flagged and
|
||||
* is recommended for
|
||||
* improvement.
|
||||
* SAST/CBOM Notes: - Parent Classification: Hybrid Cryptosystem (ECDH +
|
||||
* AES-GCM). - SAST: While ECDH and AES-GCM are secure, the key derivation
|
||||
* method here (a single SHA-256 hash) is not as robust as using a dedicated
|
||||
* KDF. This approach may be flagged and is recommended for improvement.
|
||||
*
|
||||
* @param recipientPublicKey the recipient's public EC key.
|
||||
* @param data the plaintext data to encrypt.
|
||||
* @param data the plaintext data to encrypt.
|
||||
*/
|
||||
public void ecdhHybridEncryption(PublicKey recipientPublicKey, String data) throws Exception {
|
||||
// Generate an ephemeral EC key pair for the sender.
|
||||
@@ -127,24 +114,20 @@ public class Encryption2 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs post-quantum hybrid encryption by combining a classical ECDH-derived
|
||||
* secret with a
|
||||
* post-quantum shared secret. The two secrets are combined using a custom HKDF
|
||||
* expansion, and the
|
||||
* derived key is used to encrypt data with AES-GCM.
|
||||
* Performs post-quantum hybrid encryption by combining a classical
|
||||
* ECDH-derived secret with a post-quantum shared secret. The two secrets
|
||||
* are combined using a custom HKDF expansion, and the derived key is used
|
||||
* to encrypt data with AES-GCM.
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - Parent Classification: Hybrid Cryptosystem (Classical ECDH + Post-Quantum
|
||||
* Secret + KDF + AES-GCM).
|
||||
* - SAST: The combination of classical and post-quantum secrets is a modern
|
||||
* approach. However, the
|
||||
* custom HKDF expand function is simplistic and may be flagged as insecure. Use
|
||||
* a standard HKDF
|
||||
* implementation in production.
|
||||
* SAST/CBOM Notes: - Parent Classification: Hybrid Cryptosystem (Classical
|
||||
* ECDH + Post-Quantum Secret + KDF + AES-GCM). - SAST: The combination of
|
||||
* classical and post-quantum secrets is a modern approach. However, the
|
||||
* custom HKDF expand function is simplistic and may be flagged as insecure.
|
||||
* Use a standard HKDF implementation in production.
|
||||
*
|
||||
* @param ecPublicKey the recipient's EC public key.
|
||||
* @param ecPublicKey the recipient's EC public key.
|
||||
* @param pqSharedSecret the post-quantum shared secret from a separate
|
||||
* algorithm.
|
||||
* algorithm.
|
||||
*/
|
||||
public void postQuantumHybridEncryption(PublicKey ecPublicKey, byte[] pqSharedSecret) throws Exception {
|
||||
// Step 1: Perform classical ECDH key agreement to derive a shared secret.
|
||||
@@ -171,21 +154,19 @@ public class Encryption2 {
|
||||
}
|
||||
|
||||
/**
|
||||
* A simplified HKDF expansion function that uses HMAC-SHA256 to derive a key of
|
||||
* a desired length.
|
||||
* A simplified HKDF expansion function that uses HMAC-SHA256 to derive a
|
||||
* key of a desired length.
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - Parent Classification: Key Derivation Function (KDF).
|
||||
* - SAST: Custom KDF implementations are risky if not thoroughly vetted. This
|
||||
* simple HKDF expand
|
||||
* function lacks the full HKDF mechanism (e.g., multiple iterations, info, and
|
||||
* context parameters)
|
||||
* and may be flagged. It is recommended to use a standardized HKDF library.
|
||||
* SAST/CBOM Notes: - Parent Classification: Key Derivation Function (KDF).
|
||||
* - SAST: Custom KDF implementations are risky if not thoroughly vetted.
|
||||
* This simple HKDF expand function lacks the full HKDF mechanism (e.g.,
|
||||
* multiple iterations, info, and context parameters) and may be flagged. It
|
||||
* is recommended to use a standardized HKDF library.
|
||||
*
|
||||
* @param inputKey the input key material.
|
||||
* @param salt a salt value (here, the post-quantum shared secret is used as
|
||||
* the salt).
|
||||
* @param length the desired length of the derived key.
|
||||
* @param salt a salt value (here, the post-quantum shared secret is used as
|
||||
* the salt).
|
||||
* @param length the desired length of the derived key.
|
||||
* @return a derived key of the specified length.
|
||||
*/
|
||||
private byte[] hkdfExpand(byte[] inputKey, byte[] salt, int length) throws Exception {
|
||||
|
||||
@@ -20,68 +20,56 @@ import javax.crypto.spec.PBEKeySpec;
|
||||
*
|
||||
* SAST/CBOM Classification Notes:
|
||||
*
|
||||
* 1. simpleSHA256Hash:
|
||||
* - Parent Classification: Cryptographic Hash Function.
|
||||
* - SAST: Uses SHA-256, which is widely regarded as secure.
|
||||
* 1. simpleSHA256Hash: - Parent Classification: Cryptographic Hash Function. -
|
||||
* SAST: Uses SHA-256, which is widely regarded as secure.
|
||||
*
|
||||
* 2. insecureMD5Hash:
|
||||
* - Parent Classification: Cryptographic Hash Function.
|
||||
* - SAST: MD5 is cryptographically broken and should be flagged as insecure.
|
||||
* 2. insecureMD5Hash: - Parent Classification: Cryptographic Hash Function. -
|
||||
* SAST: MD5 is cryptographically broken and should be flagged as insecure.
|
||||
*
|
||||
* 3. hashWithBouncyCastleSHA3:
|
||||
* - Parent Classification: Cryptographic Hash Function (SHA3).
|
||||
* - SAST: Uses SHA3-256 from BouncyCastle; considered secure.
|
||||
* 3. hashWithBouncyCastleSHA3: - Parent Classification: Cryptographic Hash
|
||||
* Function (SHA3). - SAST: Uses SHA3-256 from BouncyCastle; considered secure.
|
||||
*
|
||||
* 4. hashWithBouncyCastleBlake2b:
|
||||
* - Parent Classification: Cryptographic Hash Function (BLAKE2).
|
||||
* - SAST: Uses BLAKE2b-512; considered secure if used correctly.
|
||||
* 4. hashWithBouncyCastleBlake2b: - Parent Classification: Cryptographic Hash
|
||||
* Function (BLAKE2). - SAST: Uses BLAKE2b-512; considered secure if used
|
||||
* correctly.
|
||||
*
|
||||
* 5. hashAndSign & verifyHashSignature:
|
||||
* - Parent Classification: Digital Signature (RSA-based).
|
||||
* - SAST: Uses SHA256withRSA for signing and verification; secure if key
|
||||
* management is proper.
|
||||
* 5. hashAndSign & verifyHashSignature: - Parent Classification: Digital
|
||||
* Signature (RSA-based). - SAST: Uses SHA256withRSA for signing and
|
||||
* verification; secure if key management is proper.
|
||||
*
|
||||
* 6. hashForDataIntegrityCheck:
|
||||
* - Parent Classification: Data Integrity Check.
|
||||
* 6. hashForDataIntegrityCheck: - Parent Classification: Data Integrity Check.
|
||||
* - SAST: Uses SHA-256 to verify integrity; considered secure.
|
||||
*
|
||||
* 7. hashWithVariousAlgorithms:
|
||||
* - Parent Classification: Cryptographic Hash Function.
|
||||
* - SAST: Iterates through multiple algorithms; insecure algorithms (MD5,
|
||||
* SHA-1) may be flagged.
|
||||
* 7. hashWithVariousAlgorithms: - Parent Classification: Cryptographic Hash
|
||||
* Function. - SAST: Iterates through multiple algorithms; insecure algorithms
|
||||
* (MD5, SHA-1) may be flagged.
|
||||
*
|
||||
* 8. hmacWithVariousAlgorithms:
|
||||
* - Parent Classification: Message Authentication Code (MAC).
|
||||
* - SAST: Iterates through various HMAC algorithms; HmacSHA1 is considered
|
||||
* weaker than SHA256 and above.
|
||||
* 8. hmacWithVariousAlgorithms: - Parent Classification: Message Authentication
|
||||
* Code (MAC). - SAST: Iterates through various HMAC algorithms; HmacSHA1 is
|
||||
* considered weaker than SHA256 and above.
|
||||
*
|
||||
* 9. hashForPasswordStorage:
|
||||
* - Parent Classification: Password-Based Key Derivation Function (PBKDF).
|
||||
* - SAST: Uses PBKDF2WithHmacSHA256 with salt and iteration count; considered
|
||||
* secure,
|
||||
* though iteration counts should be reviewed against current standards.
|
||||
* 9. hashForPasswordStorage: - Parent Classification: Password-Based Key
|
||||
* Derivation Function (PBKDF). - SAST: Uses PBKDF2WithHmacSHA256 with salt and
|
||||
* iteration count; considered secure, though iteration counts should be
|
||||
* reviewed against current standards.
|
||||
*
|
||||
* 10. hashFromUnknownConfig:
|
||||
* - Parent Classification: Dynamic Cryptographic Hash Function.
|
||||
* - SAST: Loading the hash algorithm from an external configuration introduces
|
||||
* risk of misconfiguration.
|
||||
* 10. hashFromUnknownConfig: - Parent Classification: Dynamic Cryptographic
|
||||
* Hash Function. - SAST: Loading the hash algorithm from an external
|
||||
* configuration introduces risk of misconfiguration.
|
||||
*
|
||||
* 11. insecureHashBasedRNG:
|
||||
* - Parent Classification: Pseudo-Random Number Generator (PRNG) using hash.
|
||||
* - SAST: Uses a fixed seed with various hash algorithms; flagged as insecure
|
||||
* due to predictability.
|
||||
* 11. insecureHashBasedRNG: - Parent Classification: Pseudo-Random Number
|
||||
* Generator (PRNG) using hash. - SAST: Uses a fixed seed with various hash
|
||||
* algorithms; flagged as insecure due to predictability.
|
||||
*/
|
||||
public class Hash {
|
||||
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
/**
|
||||
* Computes a SHA-256 hash of static test data.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Uses SHA-256: Classified as secure.
|
||||
* CBOM/SAST Classification: - Uses SHA-256: Classified as secure.
|
||||
*/
|
||||
public void simpleSHA256Hash() throws Exception {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
@@ -92,9 +80,8 @@ public class Hash {
|
||||
/**
|
||||
* Computes an MD5 hash of static data.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Uses MD5: Classified as insecure.
|
||||
* - SAST: MD5 is deprecated for cryptographic purposes due to collision
|
||||
* CBOM/SAST Classification: - Uses MD5: Classified as insecure. - SAST: MD5
|
||||
* is deprecated for cryptographic purposes due to collision
|
||||
* vulnerabilities.
|
||||
*/
|
||||
public void insecureMD5Hash() throws Exception {
|
||||
@@ -118,8 +105,6 @@ public class Hash {
|
||||
// digest.doFinal(hash, 0);
|
||||
// System.out.println("SHA3-256 (BC) Hash: " + Base64.getEncoder().encodeToString(hash));
|
||||
// }
|
||||
|
||||
|
||||
// /**
|
||||
// * Computes a BLAKE2b-512 hash using BouncyCastle's Blake2bDigest.
|
||||
// *
|
||||
@@ -135,16 +120,14 @@ public class Hash {
|
||||
// digest.doFinal(hash, 0);
|
||||
// System.out.println("BLAKE2b-512 (BC) Hash: " + Base64.getEncoder().encodeToString(hash));
|
||||
// }
|
||||
|
||||
/**
|
||||
* Signs the hash of the input using SHA256withRSA.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Digital Signature (RSA): Classified as secure if keys are managed
|
||||
* correctly.
|
||||
* - SAST: The combination of SHA256 and RSA is a standard and secure pattern.
|
||||
* CBOM/SAST Classification: - Digital Signature (RSA): Classified as secure
|
||||
* if keys are managed correctly. - SAST: The combination of SHA256 and RSA
|
||||
* is a standard and secure pattern.
|
||||
*
|
||||
* @param input The input data to be signed.
|
||||
* @param input The input data to be signed.
|
||||
* @param privateKey The RSA private key used for signing.
|
||||
*/
|
||||
public void hashAndSign(String input, PrivateKey privateKey) throws Exception {
|
||||
@@ -158,15 +141,14 @@ public class Hash {
|
||||
/**
|
||||
* Verifies the signature of the input data.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Digital Signature Verification: Classified as secure when using
|
||||
* SHA256withRSA.
|
||||
* - SAST: Should correctly verify that the signed hash matches the input.
|
||||
* CBOM/SAST Classification: - Digital Signature Verification: Classified as
|
||||
* secure when using SHA256withRSA. - SAST: Should correctly verify that the
|
||||
* signed hash matches the input.
|
||||
*
|
||||
* @param input The original input data.
|
||||
* @param input The original input data.
|
||||
* @param signedHash The signed hash to verify.
|
||||
* @param publicKey The RSA public key corresponding to the private key that
|
||||
* signed the data.
|
||||
* @param publicKey The RSA public key corresponding to the private key that
|
||||
* signed the data.
|
||||
* @return true if the signature is valid, false otherwise.
|
||||
*/
|
||||
public boolean verifyHashSignature(String input, byte[] signedHash, PublicKey publicKey) throws Exception {
|
||||
@@ -177,15 +159,14 @@ public class Hash {
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a SHA-256 hash for data integrity checking and compares it with an
|
||||
* expected hash.
|
||||
* Computes a SHA-256 hash for data integrity checking and compares it with
|
||||
* an expected hash.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Data Integrity: Uses SHA-256 for integrity checks, which is secure.
|
||||
* - SAST: A correct implementation for verifying data has not been tampered
|
||||
* with.
|
||||
* CBOM/SAST Classification: - Data Integrity: Uses SHA-256 for integrity
|
||||
* checks, which is secure. - SAST: A correct implementation for verifying
|
||||
* data has not been tampered with.
|
||||
*
|
||||
* @param data The input data.
|
||||
* @param data The input data.
|
||||
* @param expectedHash The expected Base64-encoded hash.
|
||||
*/
|
||||
public void hashForDataIntegrityCheck(String data, String expectedHash) throws Exception {
|
||||
@@ -199,17 +180,16 @@ public class Hash {
|
||||
/**
|
||||
* Computes hashes of the input data using various algorithms.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Cryptographic Hash Functions: Iterates through multiple hash functions.
|
||||
* - SAST: While many are secure (e.g., SHA-256, SHA-512, SHA3), MD5 and SHA-1
|
||||
* are insecure
|
||||
* and should be flagged if used in security-critical contexts.
|
||||
* CBOM/SAST Classification: - Cryptographic Hash Functions: Iterates
|
||||
* through multiple hash functions. - SAST: While many are secure (e.g.,
|
||||
* SHA-256, SHA-512, SHA3), MD5 and SHA-1 are insecure and should be flagged
|
||||
* if used in security-critical contexts.
|
||||
*
|
||||
* @param input The input data to hash.
|
||||
*/
|
||||
public void hashWithVariousAlgorithms(String input) throws Exception {
|
||||
String[] algorithms = { "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512", "SHA3-256", "SHA3-512",
|
||||
"BLAKE2B-512", "BLAKE2S-256", "MD5" };
|
||||
String[] algorithms = {"SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512", "SHA3-256", "SHA3-512",
|
||||
"BLAKE2B-512", "BLAKE2S-256", "MD5"};
|
||||
for (String algorithm : algorithms) {
|
||||
MessageDigest digest = MessageDigest.getInstance(algorithm);
|
||||
byte[] hash = digest.digest(input.getBytes());
|
||||
@@ -220,18 +200,16 @@ public class Hash {
|
||||
/**
|
||||
* Computes HMACs of the input data using various algorithms.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Message Authentication Code (MAC): Iterates through different HMAC
|
||||
* algorithms.
|
||||
* - SAST: HmacSHA256, HmacSHA384, HmacSHA512, HmacSHA3-256, and HmacSHA3-512
|
||||
* are secure;
|
||||
* HmacSHA1 is considered less secure and may be flagged.
|
||||
* CBOM/SAST Classification: - Message Authentication Code (MAC): Iterates
|
||||
* through different HMAC algorithms. - SAST: HmacSHA256, HmacSHA384,
|
||||
* HmacSHA512, HmacSHA3-256, and HmacSHA3-512 are secure; HmacSHA1 is
|
||||
* considered less secure and may be flagged.
|
||||
*
|
||||
* @param input The input data.
|
||||
* @param key The secret key used for HMAC computation.
|
||||
* @param key The secret key used for HMAC computation.
|
||||
*/
|
||||
public void hmacWithVariousAlgorithms(String input, byte[] key) throws Exception {
|
||||
String[] algorithms = { "HmacSHA1", "HmacSHA256", "HmacSHA384", "HmacSHA512", "HmacSHA3-256", "HmacSHA3-512" };
|
||||
String[] algorithms = {"HmacSHA1", "HmacSHA256", "HmacSHA384", "HmacSHA512", "HmacSHA3-256", "HmacSHA3-512"};
|
||||
for (String algorithm : algorithms) {
|
||||
Mac mac = Mac.getInstance(algorithm);
|
||||
SecretKey secretKey = new SecretKeySpec(key, algorithm);
|
||||
@@ -244,12 +222,10 @@ public class Hash {
|
||||
/**
|
||||
* Computes a PBKDF2 hash for password storage.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Password-Based Key Derivation Function (PBKDF): Uses PBKDF2WithHmacSHA256.
|
||||
* - SAST: Considered secure when using a strong salt and an appropriate
|
||||
* iteration count.
|
||||
* Note: The iteration count (10000) should be reviewed against current security
|
||||
* standards.
|
||||
* CBOM/SAST Classification: - Password-Based Key Derivation Function
|
||||
* (PBKDF): Uses PBKDF2WithHmacSHA256. - SAST: Considered secure when using
|
||||
* a strong salt and an appropriate iteration count. Note: The iteration
|
||||
* count (10000) should be reviewed against current security standards.
|
||||
*
|
||||
* @param password The password to hash.
|
||||
*/
|
||||
@@ -263,50 +239,47 @@ public class Hash {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically loads a hash algorithm from configuration and computes a hash.
|
||||
* Dynamically loads a hash algorithm from configuration and computes a
|
||||
* hash.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Dynamic Cryptographic Hash Selection: Algorithm is loaded from a config
|
||||
* file.
|
||||
* - SAST: May be flagged as risky because an insecure or unintended algorithm
|
||||
* might be chosen.
|
||||
* CBOM/SAST Classification: - Dynamic Cryptographic Hash Selection:
|
||||
* Algorithm is loaded from a config file. - SAST: May be flagged as risky
|
||||
* because an insecure or unintended algorithm might be chosen.
|
||||
*/
|
||||
public void hashFromUnknownConfig() throws Exception {
|
||||
String algorithm = loadHashAlgorithmFromConfig("config.properties");
|
||||
MessageDigest digest = MessageDigest.getInstance(algorithm);
|
||||
byte[] hash = digest.digest("Config-based Hashing".getBytes());
|
||||
System.out.println("Dynamically Loaded Hash Algorithm (" + algorithm + "): " +
|
||||
Base64.getEncoder().encodeToString(hash));
|
||||
System.out.println("Dynamically Loaded Hash Algorithm (" + algorithm + "): "
|
||||
+ Base64.getEncoder().encodeToString(hash));
|
||||
}
|
||||
|
||||
/**
|
||||
* Demonstrates an insecure method for generating pseudo-random bytes by using a
|
||||
* fixed seed with hash algorithms.
|
||||
* Demonstrates an insecure method for generating pseudo-random bytes by
|
||||
* using a fixed seed with hash algorithms.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Insecure RNG: Uses a fixed seed with various hash algorithms.
|
||||
* - SAST: This approach is insecure because it produces predictable output and
|
||||
* should be flagged.
|
||||
* CBOM/SAST Classification: - Insecure RNG: Uses a fixed seed with various
|
||||
* hash algorithms. - SAST: This approach is insecure because it produces
|
||||
* predictable output and should be flagged.
|
||||
*/
|
||||
public void insecureHashBasedRNG() throws Exception {
|
||||
String[] algorithms = { "SHA-256", "SHA-512", "SHA3-256", "SHA3-512" };
|
||||
String[] algorithms = {"SHA-256", "SHA-512", "SHA3-256", "SHA3-512"};
|
||||
for (String algorithm : algorithms) {
|
||||
MessageDigest digest = MessageDigest.getInstance(algorithm);
|
||||
byte[] seed = "fixed-seed".getBytes(); // Fixed seed: insecure and predictable.
|
||||
digest.update(seed);
|
||||
byte[] pseudoRandomBytes = digest.digest();
|
||||
System.out.println("Insecure RNG using " + algorithm + ": " +
|
||||
Base64.getEncoder().encodeToString(pseudoRandomBytes));
|
||||
System.out.println("Insecure RNG using " + algorithm + ": "
|
||||
+ Base64.getEncoder().encodeToString(pseudoRandomBytes));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the hash algorithm from an external configuration file.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Dynamic Configuration: External config loading.
|
||||
* - SAST: The use of external configuration may introduce risks if the config
|
||||
* file is compromised.
|
||||
* CBOM/SAST Classification: - Dynamic Configuration: External config
|
||||
* loading. - SAST: The use of external configuration may introduce risks if
|
||||
* the config file is compromised.
|
||||
*
|
||||
* @param configPath Path to the configuration file.
|
||||
* @return The hash algorithm to be used (default is SHA-256).
|
||||
@@ -325,9 +298,8 @@ public class Hash {
|
||||
* Generates a secure salt using a cryptographically strong random number
|
||||
* generator.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Secure Salt Generation: Uses SecureRandom.
|
||||
* - SAST: This is a best-practice approach for generating salts for password
|
||||
* CBOM/SAST Classification: - Secure Salt Generation: Uses SecureRandom. -
|
||||
* SAST: This is a best-practice approach for generating salts for password
|
||||
* hashing.
|
||||
*
|
||||
* @param length The desired salt length.
|
||||
|
||||
@@ -20,9 +20,9 @@ public class IVArtifact {
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider()); // Ensure BouncyCastle is available
|
||||
// }
|
||||
|
||||
/**
|
||||
* Simple Case: Generates a secure IV and encrypts with AES/CBC/PKCS5Padding.
|
||||
* Simple Case: Generates a secure IV and encrypts with
|
||||
* AES/CBC/PKCS5Padding.
|
||||
*/
|
||||
public void simpleIVEncryption() throws Exception {
|
||||
SecretKey key = generateAESKey();
|
||||
@@ -91,13 +91,12 @@ public class IVArtifact {
|
||||
// -------------------------------
|
||||
// 1. Direct Fixed IV Usage
|
||||
// -------------------------------
|
||||
|
||||
/**
|
||||
* Encrypts plaintext using AES-GCM with a fixed IV (all zeros).
|
||||
* This is an insecure practice as IV reuse in AES-GCM undermines
|
||||
* confidentiality and integrity.
|
||||
* Encrypts plaintext using AES-GCM with a fixed IV (all zeros). This is an
|
||||
* insecure practice as IV reuse in AES-GCM undermines confidentiality and
|
||||
* integrity.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -113,7 +112,6 @@ public class IVArtifact {
|
||||
// -------------------------------
|
||||
// 2. Cached IV Usage
|
||||
// -------------------------------
|
||||
|
||||
// Cache an IV for reuse in multiple encryptions (insecure)
|
||||
private byte[] cachedIV = null;
|
||||
|
||||
@@ -121,7 +119,7 @@ public class IVArtifact {
|
||||
* Encrypts plaintext using AES-GCM with an IV cached from the first call.
|
||||
* Reusing the same IV across multiple encryptions is insecure.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -140,15 +138,13 @@ public class IVArtifact {
|
||||
// -------------------------------
|
||||
// 3. Indirect IV Reuse via Deterministic Derivation
|
||||
// -------------------------------
|
||||
|
||||
/**
|
||||
* Encrypts plaintext using AES-GCM with an IV derived deterministically from a
|
||||
* constant.
|
||||
* This method computes a SHA-256 hash of a constant string and uses the first
|
||||
* 12 bytes as the IV.
|
||||
* Such derived IVs are fixed and must not be reused.
|
||||
* Encrypts plaintext using AES-GCM with an IV derived deterministically
|
||||
* from a constant. This method computes a SHA-256 hash of a constant string
|
||||
* and uses the first 12 bytes as the IV. Such derived IVs are fixed and
|
||||
* must not be reused.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -166,14 +162,12 @@ public class IVArtifact {
|
||||
// -------------------------------
|
||||
// 4. Reusing a Single IV Across Multiple Messages
|
||||
// -------------------------------
|
||||
|
||||
/**
|
||||
* Encrypts an array of plaintext messages using AES-GCM with the same IV for
|
||||
* every message.
|
||||
* Reusing an IV across messages is insecure in authenticated encryption
|
||||
* schemes.
|
||||
* Encrypts an array of plaintext messages using AES-GCM with the same IV
|
||||
* for every message. Reusing an IV across messages is insecure in
|
||||
* authenticated encryption schemes.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintexts An array of plaintext messages.
|
||||
* @return An array of ciphertexts.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -194,8 +188,8 @@ public class IVArtifact {
|
||||
/**
|
||||
* Encrypts the given plaintext using AES-GCM with the provided key and IV.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param ivSpec The IV specification.
|
||||
* @param key The AES key.
|
||||
* @param ivSpec The IV specification.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext (IV is not prepended here for clarity).
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -212,10 +206,10 @@ public class IVArtifact {
|
||||
* Example 1: Reuses the same IvParameterSpec object across two encryption
|
||||
* calls.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return An array containing two ciphertexts generated with the same
|
||||
* IvParameterSpec.
|
||||
* IvParameterSpec.
|
||||
* @throws Exception if encryption fails.
|
||||
*/
|
||||
public byte[][] encryptUsingSameIvParameterSpec(SecretKey key, byte[] plaintext) throws Exception {
|
||||
@@ -225,18 +219,17 @@ public class IVArtifact {
|
||||
// Encrypt the plaintext twice using the same IvParameterSpec.
|
||||
byte[] ciphertext1 = encrypt(key, fixedIvSpec, plaintext);
|
||||
byte[] ciphertext2 = encrypt(key, fixedIvSpec, plaintext);
|
||||
return new byte[][] { ciphertext1, ciphertext2 };
|
||||
return new byte[][]{ciphertext1, ciphertext2};
|
||||
}
|
||||
|
||||
/**
|
||||
* Example 2: Creates two different IvParameterSpec objects that share the same
|
||||
* underlying IV array.
|
||||
* Example 2: Creates two different IvParameterSpec objects that share the
|
||||
* same underlying IV array.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return An array containing two ciphertexts generated with two
|
||||
* IvParameterSpec objects
|
||||
* constructed from the same IV array.
|
||||
* IvParameterSpec objects constructed from the same IV array.
|
||||
* @throws Exception if encryption fails.
|
||||
*/
|
||||
public byte[][] encryptUsingDifferentIvSpecSameIVArray(SecretKey key, byte[] plaintext) throws Exception {
|
||||
@@ -248,13 +241,12 @@ public class IVArtifact {
|
||||
// Encrypt the plaintext twice.
|
||||
byte[] ciphertext1 = encrypt(key, ivSpec1, plaintext);
|
||||
byte[] ciphertext2 = encrypt(key, ivSpec2, plaintext);
|
||||
return new byte[][] { ciphertext1, ciphertext2 };
|
||||
return new byte[][]{ciphertext1, ciphertext2};
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// Main Method for Demonstration
|
||||
// -------------------------------
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
IVArtifact test = new IVArtifact();
|
||||
@@ -280,7 +272,7 @@ public class IVArtifact {
|
||||
System.out.println("Derived IV Encryption: " + Base64.getEncoder().encodeToString(derivedIVCipher));
|
||||
|
||||
// Example 4: Reusing the same IV across multiple messages
|
||||
byte[][] messages = { "Message One".getBytes(), "Message Two".getBytes(), "Message Three".getBytes() };
|
||||
byte[][] messages = {"Message One".getBytes(), "Message Two".getBytes(), "Message Three".getBytes()};
|
||||
byte[][] multiCiphers = test.encryptMultipleMessagesWithSameIV(key, messages);
|
||||
for (int i = 0; i < multiCiphers.length; i++) {
|
||||
System.out.println("Multi-message Encryption " + (i + 1) + ": "
|
||||
|
||||
@@ -2,7 +2,10 @@ package com.example.crypto.algorithms;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
// import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyAgreement;
|
||||
import javax.crypto.KeyGenerator;
|
||||
@@ -13,35 +16,24 @@ import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* KeyAgreementHybridCryptosystem demonstrates two hybrid cryptosystems:
|
||||
*
|
||||
* 1. ECDH + AES-GCM:
|
||||
* - Secure Flow: Uses ephemeral ECDH key pairs on secp256r1, applies a simple
|
||||
* KDF (SHA-256)
|
||||
* to derive a 128-bit AES key, and uses AES-GCM with a random 12-byte nonce.
|
||||
* - Insecure Flow: Reuses a static key pair, uses raw shared secret truncation,
|
||||
* and employs
|
||||
* a fixed (zero) IV.
|
||||
* 1. ECDH + AES-GCM: - Secure Flow: Uses ephemeral ECDH key pairs on secp256r1,
|
||||
* applies a simple KDF (SHA-256) to derive a 128-bit AES key, and uses AES-GCM
|
||||
* with a random 12-byte nonce. - Insecure Flow: Reuses a static key pair, uses
|
||||
* raw shared secret truncation, and employs a fixed (zero) IV.
|
||||
*
|
||||
* 2. X25519 + ChaCha20-Poly1305:
|
||||
* - Secure Flow: Uses ephemeral X25519 key pairs, applies a KDF (SHA-256) to
|
||||
* derive a 256-bit key,
|
||||
* and uses ChaCha20-Poly1305 with a random nonce.
|
||||
* - Insecure Flow: Reuses a static key pair, directly truncates the shared
|
||||
* secret without a proper KDF,
|
||||
* and uses a fixed nonce.
|
||||
* 2. X25519 + ChaCha20-Poly1305: - Secure Flow: Uses ephemeral X25519 key
|
||||
* pairs, applies a KDF (SHA-256) to derive a 256-bit key, and uses
|
||||
* ChaCha20-Poly1305 with a random nonce. - Insecure Flow: Reuses a static key
|
||||
* pair, directly truncates the shared secret without a proper KDF, and uses a
|
||||
* fixed nonce.
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - Secure flows use proper ephemeral key generation, a simple KDF, and random
|
||||
* nonces.
|
||||
* - Insecure flows use static keys, fixed nonces, and raw shared secret
|
||||
* truncation.
|
||||
* SAST/CBOM Notes: - Secure flows use proper ephemeral key generation, a simple
|
||||
* KDF, and random nonces. - Insecure flows use static keys, fixed nonces, and
|
||||
* raw shared secret truncation.
|
||||
*/
|
||||
public class KeyAgreementHybridCryptosystem {
|
||||
|
||||
@@ -49,9 +41,7 @@ public class KeyAgreementHybridCryptosystem {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// Security.addProvider(new BouncyCastlePQCProvider());
|
||||
// }
|
||||
|
||||
// ---------- Helper Methods ----------
|
||||
|
||||
/**
|
||||
* Generates an ephemeral ECDH key pair on secp256r1.
|
||||
*/
|
||||
@@ -103,11 +93,10 @@ public class KeyAgreementHybridCryptosystem {
|
||||
// ===============================================
|
||||
// 1. ECDH + AES-GCM Flows
|
||||
// ===============================================
|
||||
|
||||
/**
|
||||
* Secure hybrid encryption using ECDH and AES-GCM.
|
||||
* Uses ephemeral key pairs, applies a simple KDF to derive a 128-bit AES key,
|
||||
* and uses AES-GCM with a random 12-byte nonce.
|
||||
* Secure hybrid encryption using ECDH and AES-GCM. Uses ephemeral key
|
||||
* pairs, applies a simple KDF to derive a 128-bit AES key, and uses AES-GCM
|
||||
* with a random 12-byte nonce.
|
||||
*/
|
||||
public byte[] secureECDH_AESGCMEncryption(byte[] plaintext) throws Exception {
|
||||
KeyPair aliceKP = generateECDHKeyPair();
|
||||
@@ -127,10 +116,9 @@ public class KeyAgreementHybridCryptosystem {
|
||||
}
|
||||
|
||||
/**
|
||||
* Insecure hybrid encryption using ECDH and AES-GCM.
|
||||
* Reuses a static key pair, uses raw shared secret truncation without a proper
|
||||
* KDF,
|
||||
* and employs a fixed IV (all zeros).
|
||||
* Insecure hybrid encryption using ECDH and AES-GCM. Reuses a static key
|
||||
* pair, uses raw shared secret truncation without a proper KDF, and employs
|
||||
* a fixed IV (all zeros).
|
||||
*/
|
||||
public byte[] insecureECDH_AESGCMEncryption(byte[] plaintext) throws Exception {
|
||||
KeyPair staticKP = generateECDHKeyPair();
|
||||
@@ -150,11 +138,10 @@ public class KeyAgreementHybridCryptosystem {
|
||||
// ===============================================
|
||||
// 2. X25519 + ChaCha20-Poly1305 Flows
|
||||
// ===============================================
|
||||
|
||||
/**
|
||||
* Secure hybrid encryption using X25519 and ChaCha20-Poly1305.
|
||||
* Uses ephemeral key pairs, applies a KDF (SHA-256) to derive a 256-bit key,
|
||||
* and uses ChaCha20-Poly1305 with a random 12-byte nonce.
|
||||
* Secure hybrid encryption using X25519 and ChaCha20-Poly1305. Uses
|
||||
* ephemeral key pairs, applies a KDF (SHA-256) to derive a 256-bit key, and
|
||||
* uses ChaCha20-Poly1305 with a random 12-byte nonce.
|
||||
*/
|
||||
public byte[] secureX25519_Chacha20Poly1305Encryption(byte[] plaintext) throws Exception {
|
||||
KeyPair aliceKP = generateX25519KeyPair();
|
||||
@@ -173,10 +160,9 @@ public class KeyAgreementHybridCryptosystem {
|
||||
}
|
||||
|
||||
/**
|
||||
* Insecure hybrid encryption using X25519 and ChaCha20-Poly1305.
|
||||
* Reuses a static key pair, directly truncates the shared secret without a
|
||||
* proper KDF,
|
||||
* and employs a fixed nonce.
|
||||
* Insecure hybrid encryption using X25519 and ChaCha20-Poly1305. Reuses a
|
||||
* static key pair, directly truncates the shared secret without a proper
|
||||
* KDF, and employs a fixed nonce.
|
||||
*/
|
||||
public byte[] insecureX25519_Chacha20Poly1305Encryption(byte[] plaintext) throws Exception {
|
||||
KeyPair staticKP = generateX25519KeyPair();
|
||||
@@ -195,11 +181,9 @@ public class KeyAgreementHybridCryptosystem {
|
||||
// ===============================================
|
||||
// 3. Dynamic Hybrid Selection
|
||||
// ===============================================
|
||||
|
||||
/**
|
||||
* Dynamically selects a hybrid encryption flow based on a configuration
|
||||
* property.
|
||||
* If the config is unknown, defaults to an insecure flow.
|
||||
* property. If the config is unknown, defaults to an insecure flow.
|
||||
*/
|
||||
public String dynamicHybridEncryption(String config, byte[] plaintext) throws Exception {
|
||||
byte[] result;
|
||||
@@ -221,11 +205,9 @@ public class KeyAgreementHybridCryptosystem {
|
||||
// ===============================================
|
||||
// 4. Further Key Derivation from Symmetric Keys
|
||||
// ===============================================
|
||||
|
||||
/**
|
||||
* Derives two keys from a symmetric key using PBKDF2, then uses one key for
|
||||
* AES-GCM encryption
|
||||
* and the other for computing a MAC over the ciphertext.
|
||||
* AES-GCM encryption and the other for computing a MAC over the ciphertext.
|
||||
*/
|
||||
public byte[] furtherUseSymmetricKeyForKeyDerivation(SecretKey key, byte[] plaintext) throws Exception {
|
||||
String keyAsString = Base64.getEncoder().encodeToString(key.getEncoded());
|
||||
@@ -259,7 +241,6 @@ public class KeyAgreementHybridCryptosystem {
|
||||
// ===============================================
|
||||
// 5. Output/Storage Methods
|
||||
// ===============================================
|
||||
|
||||
/**
|
||||
* Stores the output securely.
|
||||
*/
|
||||
@@ -271,7 +252,6 @@ public class KeyAgreementHybridCryptosystem {
|
||||
// ===============================================
|
||||
// 6. Helper Methods for Key/Nonce Generation
|
||||
// ===============================================
|
||||
|
||||
/**
|
||||
* Generates a secure 256-bit AES key.
|
||||
*/
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package com.example.crypto.artifacts;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import java.io.FileInputStream;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Properties;
|
||||
import java.io.FileInputStream;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
public class KeyArtifact {
|
||||
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
public void generateSymmetricKeys() throws NoSuchAlgorithmException {
|
||||
// AES Key Generation (Default Provider)
|
||||
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
|
||||
@@ -76,7 +75,7 @@ public class KeyArtifact {
|
||||
|
||||
public void keySelectionFromArray() throws NoSuchAlgorithmException {
|
||||
// Selecting Algorithm Dynamically from an Array
|
||||
String[] algorithms = { "RSA", "EC", "Ed25519" };
|
||||
String[] algorithms = {"RSA", "EC", "Ed25519"};
|
||||
KeyPair[] keyPairs = new KeyPair[algorithms.length];
|
||||
|
||||
for (int i = 0; i < algorithms.length; i++) {
|
||||
|
||||
@@ -3,81 +3,67 @@ package com.example.crypto.algorithms;
|
||||
// import org.bouncycastle.crypto.generators.Argon2BytesGenerator;
|
||||
// import org.bouncycastle.crypto.params.Argon2Parameters;
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Properties;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* This class demonstrates multiple key derivation functions (KDFs) including
|
||||
* PBKDF2, scrypt, Argon2, raw hash derivation,
|
||||
* HKDF, and dynamic algorithm selection.
|
||||
* PBKDF2, scrypt, Argon2, raw hash derivation, HKDF, and dynamic algorithm
|
||||
* selection.
|
||||
*
|
||||
* SAST/CBOM Classification Notes:
|
||||
*
|
||||
* 1. PBKDF2 Examples:
|
||||
* - Parent Classification: Password-Based Key Derivation Function (PBKDF).
|
||||
* - SAST:
|
||||
* * pbkdf2DerivationBasic: Uses PBKDF2WithHmacSHA256 with 10,000 iterations -
|
||||
* acceptable if parameters meet current standards.
|
||||
* * pbkdf2LowIteration: Uses only 10 iterations – flagged as insecure due to
|
||||
* insufficient iteration count.
|
||||
* * pbkdf2HighIteration: Uses 1,000,000 iterations – secure (though performance
|
||||
* may be impacted).
|
||||
* * pbkdf2HmacSHA1: Uses PBKDF2WithHmacSHA1 – flagged as weaker compared to
|
||||
* SHA-256, though sometimes seen in legacy systems.
|
||||
* * pbkdf2HmacSHA512: Uses PBKDF2WithHmacSHA512 – classified as secure.
|
||||
* 1. PBKDF2 Examples: - Parent Classification: Password-Based Key Derivation
|
||||
* Function (PBKDF). - SAST: * pbkdf2DerivationBasic: Uses PBKDF2WithHmacSHA256
|
||||
* with 10,000 iterations - acceptable if parameters meet current standards. *
|
||||
* pbkdf2LowIteration: Uses only 10 iterations – flagged as insecure due to
|
||||
* insufficient iteration count. * pbkdf2HighIteration: Uses 1,000,000
|
||||
* iterations – secure (though performance may be impacted). * pbkdf2HmacSHA1:
|
||||
* Uses PBKDF2WithHmacSHA1 – flagged as weaker compared to SHA-256, though
|
||||
* sometimes seen in legacy systems. * pbkdf2HmacSHA512: Uses
|
||||
* PBKDF2WithHmacSHA512 – classified as secure.
|
||||
*
|
||||
* 2. Scrypt Examples:
|
||||
* - Parent Classification: Memory-Hard Key Derivation Function.
|
||||
* - SAST:
|
||||
* * scryptWeak: Uses weak parameters (n=1024, r=1, p=1) – flagged as insecure.
|
||||
* * scryptStrong: Uses stronger parameters (n=16384, r=8, p=1) – considered
|
||||
* secure.
|
||||
* 2. Scrypt Examples: - Parent Classification: Memory-Hard Key Derivation
|
||||
* Function. - SAST: * scryptWeak: Uses weak parameters (n=1024, r=1, p=1) –
|
||||
* flagged as insecure. * scryptStrong: Uses stronger parameters (n=16384, r=8,
|
||||
* p=1) – considered secure.
|
||||
*
|
||||
* 3. Argon2 Examples:
|
||||
* - Parent Classification: Memory-Hard Key Derivation Function (Argon2id).
|
||||
* - SAST:
|
||||
* * argon2Derivation: Uses moderate memory and iterations – considered secure.
|
||||
* * argon2HighMemory: Uses high memory (128MB) and more iterations – secure,
|
||||
* though resource intensive.
|
||||
* 3. Argon2 Examples: - Parent Classification: Memory-Hard Key Derivation
|
||||
* Function (Argon2id). - SAST: * argon2Derivation: Uses moderate memory and
|
||||
* iterations – considered secure. * argon2HighMemory: Uses high memory (128MB)
|
||||
* and more iterations – secure, though resource intensive.
|
||||
*
|
||||
* 4. Insecure Raw Hash Derivation:
|
||||
* - Parent Classification: Raw Hash Usage for Key Derivation.
|
||||
* - SAST: Using a single SHA-256 hash as a key and then using it with insecure
|
||||
* AES/ECB mode is highly discouraged.
|
||||
* 4. Insecure Raw Hash Derivation: - Parent Classification: Raw Hash Usage for
|
||||
* Key Derivation. - SAST: Using a single SHA-256 hash as a key and then using
|
||||
* it with insecure AES/ECB mode is highly discouraged.
|
||||
*
|
||||
* 5. HKDF Examples:
|
||||
* - Parent Classification: Key Derivation Function (HKDF).
|
||||
* - SAST: The provided HKDF implementation is simplistic (single-block
|
||||
* expansion) and may be flagged.
|
||||
* 5. HKDF Examples: - Parent Classification: Key Derivation Function (HKDF). -
|
||||
* SAST: The provided HKDF implementation is simplistic (single-block expansion)
|
||||
* and may be flagged.
|
||||
*
|
||||
* 6. Multi-Step Hybrid Derivation:
|
||||
* - Parent Classification: Composite KDF (PBKDF2 followed by HKDF).
|
||||
* - SAST: Combining two KDFs is acceptable if done carefully; however, custom
|
||||
* implementations should be reviewed.
|
||||
* 6. Multi-Step Hybrid Derivation: - Parent Classification: Composite KDF
|
||||
* (PBKDF2 followed by HKDF). - SAST: Combining two KDFs is acceptable if done
|
||||
* carefully; however, custom implementations should be reviewed.
|
||||
*
|
||||
* 7. Dynamic KDF Selection:
|
||||
* - Parent Classification: Dynamic/Configurable Key Derivation.
|
||||
* - SAST: Loading KDF parameters from configuration introduces ambiguity and
|
||||
* risk if misconfigured.
|
||||
* 7. Dynamic KDF Selection: - Parent Classification: Dynamic/Configurable Key
|
||||
* Derivation. - SAST: Loading KDF parameters from configuration introduces
|
||||
* ambiguity and risk if misconfigured.
|
||||
*/
|
||||
public class KeyDerivation1 {
|
||||
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
//////////////////////////////////////
|
||||
// 1. PBKDF2 EXAMPLES
|
||||
//////////////////////////////////////
|
||||
@@ -100,11 +86,8 @@ public class KeyDerivation1 {
|
||||
/**
|
||||
* PBKDF2 derivation with a very low iteration count.
|
||||
*
|
||||
* SAST/CBOM:
|
||||
* - Parent: PBKDF2.
|
||||
* - Iteration count is only 10, which is far below acceptable security
|
||||
* standards.
|
||||
* - Flagged as insecure.
|
||||
* SAST/CBOM: - Parent: PBKDF2. - Iteration count is only 10, which is far
|
||||
* below acceptable security standards. - Flagged as insecure.
|
||||
*/
|
||||
public void pbkdf2LowIteration(String password) throws Exception {
|
||||
byte[] salt = generateSalt(16);
|
||||
@@ -117,9 +100,8 @@ public class KeyDerivation1 {
|
||||
/**
|
||||
* PBKDF2 derivation with a high iteration count.
|
||||
*
|
||||
* SAST/CBOM:
|
||||
* - Parent: PBKDF2.
|
||||
* - Uses 1,000,000 iterations; this is secure but may impact performance.
|
||||
* SAST/CBOM: - Parent: PBKDF2. - Uses 1,000,000 iterations; this is secure
|
||||
* but may impact performance.
|
||||
*/
|
||||
public void pbkdf2HighIteration(String password) throws Exception {
|
||||
byte[] salt = generateSalt(16);
|
||||
@@ -132,10 +114,8 @@ public class KeyDerivation1 {
|
||||
/**
|
||||
* PBKDF2 derivation using HmacSHA1.
|
||||
*
|
||||
* SAST/CBOM:
|
||||
* - Parent: PBKDF2.
|
||||
* - Uses HMAC-SHA1, which is considered weaker than SHA-256; may be acceptable
|
||||
* only for legacy systems.
|
||||
* SAST/CBOM: - Parent: PBKDF2. - Uses HMAC-SHA1, which is considered weaker
|
||||
* than SHA-256; may be acceptable only for legacy systems.
|
||||
*/
|
||||
public void pbkdf2HmacSHA1(String password) throws Exception {
|
||||
byte[] salt = generateSalt(16);
|
||||
@@ -148,9 +128,8 @@ public class KeyDerivation1 {
|
||||
/**
|
||||
* PBKDF2 derivation using HmacSHA512.
|
||||
*
|
||||
* SAST/CBOM:
|
||||
* - Parent: PBKDF2.
|
||||
* - Uses HMAC-SHA512 with 160,000 iterations; classified as secure.
|
||||
* SAST/CBOM: - Parent: PBKDF2. - Uses HMAC-SHA512 with 160,000 iterations;
|
||||
* classified as secure.
|
||||
*/
|
||||
public void pbkdf2HmacSHA512(String password) throws Exception {
|
||||
byte[] salt = generateSalt(16);
|
||||
@@ -184,9 +163,8 @@ public class KeyDerivation1 {
|
||||
/**
|
||||
* Scrypt derivation with stronger parameters.
|
||||
*
|
||||
* SAST/CBOM:
|
||||
* - Parent: Scrypt.
|
||||
* - Parameters (n=16384, r=8, p=1) provide a secure work factor.
|
||||
* SAST/CBOM: - Parent: Scrypt. - Parameters (n=16384, r=8, p=1) provide a
|
||||
* secure work factor.
|
||||
*/
|
||||
public void scryptStrong(String password) throws Exception {
|
||||
byte[] salt = generateSalt(16);
|
||||
@@ -298,10 +276,9 @@ public class KeyDerivation1 {
|
||||
* Multi-step hybrid derivation: first using PBKDF2, then applying HKDF
|
||||
* expansion.
|
||||
*
|
||||
* SAST/CBOM:
|
||||
* - Parent: Composite KDF.
|
||||
* - Combining PBKDF2 and HKDF is a non-standard approach and may be flagged;
|
||||
* ensure that each step meets security requirements.
|
||||
* SAST/CBOM: - Parent: Composite KDF. - Combining PBKDF2 and HKDF is a
|
||||
* non-standard approach and may be flagged; ensure that each step meets
|
||||
* security requirements.
|
||||
*/
|
||||
public void multiStepHybridDerivation(String password, byte[] sharedSecret) throws Exception {
|
||||
byte[] pbkdf2Key = derivePBKDF2Key(password);
|
||||
@@ -361,10 +338,8 @@ public class KeyDerivation1 {
|
||||
/**
|
||||
* A simplistic HKDF expansion function using HMAC-SHA256.
|
||||
*
|
||||
* SAST/CBOM:
|
||||
* - Parent: HKDF.
|
||||
* - Uses a single-block expansion ("hkdf-expansion") which is non-standard and
|
||||
* may be flagged.
|
||||
* SAST/CBOM: - Parent: HKDF. - Uses a single-block expansion
|
||||
* ("hkdf-expansion") which is non-standard and may be flagged.
|
||||
*/
|
||||
private byte[] hkdfExpand(byte[] ikm, byte[] salt, int length) throws Exception {
|
||||
Mac hmac = Mac.getInstance("HmacSHA256");
|
||||
@@ -382,9 +357,8 @@ public class KeyDerivation1 {
|
||||
/**
|
||||
* Generates a secure random salt of the specified length.
|
||||
*
|
||||
* SAST/CBOM:
|
||||
* - Parent: Secure Random Salt Generation.
|
||||
* - Uses SecureRandom; considered best practice.
|
||||
* SAST/CBOM: - Parent: Secure Random Salt Generation. - Uses SecureRandom;
|
||||
* considered best practice.
|
||||
*/
|
||||
private byte[] generateSalt(int length) {
|
||||
byte[] salt = new byte[length];
|
||||
|
||||
@@ -4,38 +4,35 @@ package com.example.crypto.algorithms;
|
||||
// import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
|
||||
// import org.bouncycastle.pqc.jcajce.spec.KyberParameterSpec;
|
||||
// import org.bouncycastle.util.Strings;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyAgreement;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* Demonstrates various Key Encapsulation Mechanisms (KEMs), including:
|
||||
*
|
||||
* 1) RSA-KEM (emulated using RSA-OAEP for ephemeral key wrapping)
|
||||
* - CBOM/SAST: Classified as a Hybrid Cryptosystem (public-key based key
|
||||
* encapsulation).
|
||||
* 1) RSA-KEM (emulated using RSA-OAEP for ephemeral key wrapping) - CBOM/SAST:
|
||||
* Classified as a Hybrid Cryptosystem (public-key based key encapsulation).
|
||||
* While RSA-OAEP is secure, using it to emulate KEM (without a standard scheme)
|
||||
* may be flagged.
|
||||
*
|
||||
* 2) ECIES (Elliptic Curve Integrated Encryption Scheme)
|
||||
* - CBOM/SAST: Classified as a Hybrid Cryptosystem (KEM+DEM) based on ECDH and
|
||||
* AES.
|
||||
* Note: Directly using the raw ECDH shared secret as key material is insecure
|
||||
* in production.
|
||||
* 2) ECIES (Elliptic Curve Integrated Encryption Scheme) - CBOM/SAST:
|
||||
* Classified as a Hybrid Cryptosystem (KEM+DEM) based on ECDH and AES. Note:
|
||||
* Directly using the raw ECDH shared secret as key material is insecure in
|
||||
* production.
|
||||
*
|
||||
* 3) Kyber (Post-Quantum KEM using BouncyCastle PQC)
|
||||
* - CBOM/SAST: Classified as a Post-Quantum Key Encapsulation mechanism.
|
||||
* This is modern and secure when using standardized parameters.
|
||||
* 3) Kyber (Post-Quantum KEM using BouncyCastle PQC) - CBOM/SAST: Classified as
|
||||
* a Post-Quantum Key Encapsulation mechanism. This is modern and secure when
|
||||
* using standardized parameters.
|
||||
*
|
||||
* 4) Basic ephemeral flows that mimic KEM logic using ephemeral ECDH.
|
||||
* - CBOM/SAST: Classified as a simple KEM mimic based on ephemeral ECDH.
|
||||
* 4) Basic ephemeral flows that mimic KEM logic using ephemeral ECDH. -
|
||||
* CBOM/SAST: Classified as a simple KEM mimic based on ephemeral ECDH.
|
||||
*/
|
||||
public class KeyEncapsulation {
|
||||
|
||||
@@ -44,7 +41,6 @@ public class KeyEncapsulation {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// Security.addProvider(new BouncyCastlePQCProvider());
|
||||
// }
|
||||
|
||||
//////////////////////////////////////
|
||||
// 1. RSA-KEM-Like Flow
|
||||
//////////////////////////////////////
|
||||
@@ -86,11 +82,10 @@ public class KeyEncapsulation {
|
||||
/**
|
||||
* Performs RSA decapsulation by decrypting the wrapped AES key.
|
||||
*
|
||||
* SAST/CBOM Classification:
|
||||
* - Parent: Hybrid Cryptosystem (RSA-OAEP based key decapsulation).
|
||||
* - Note: Secure when used with matching RSA key pairs.
|
||||
* SAST/CBOM Classification: - Parent: Hybrid Cryptosystem (RSA-OAEP based
|
||||
* key decapsulation). - Note: Secure when used with matching RSA key pairs.
|
||||
*
|
||||
* @param rsaPriv The RSA private key corresponding to the public key used.
|
||||
* @param rsaPriv The RSA private key corresponding to the public key used.
|
||||
* @param wrappedKey The RSA-wrapped ephemeral AES key.
|
||||
*/
|
||||
public void rsaKEMDecapsulation(PrivateKey rsaPriv, byte[] wrappedKey) throws Exception {
|
||||
@@ -225,7 +220,6 @@ public class KeyEncapsulation {
|
||||
// kyberKpg.initialize(KyberParameterSpec.kyber512);
|
||||
// KeyPair kyberKP = kyberKpg.generateKeyPair();
|
||||
// kyberEncapsulate(kyberKP);
|
||||
|
||||
// 4) Ephemeral ECDH Mimic KEM:
|
||||
// For demonstration, we use an EC key pair and mimic KEM by deriving a shared
|
||||
// secret.
|
||||
|
||||
@@ -1,35 +1,30 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import javax.crypto.KeyAgreement;
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.KeyAgreement;
|
||||
|
||||
/**
|
||||
* Demonstrates various Key Exchange mechanisms using standard Java and
|
||||
* BouncyCastle:
|
||||
*
|
||||
* 1) Classic DH (Diffie-Hellman) with multiple key sizes:
|
||||
* - 512-bit: Insecure/deprecated (flagged as unsafe by SAST).
|
||||
* - 2048-bit: Standard secure level.
|
||||
* - 4096-bit: High-security (but can be slow).
|
||||
* 1) Classic DH (Diffie-Hellman) with multiple key sizes: - 512-bit:
|
||||
* Insecure/deprecated (flagged as unsafe by SAST). - 2048-bit: Standard secure
|
||||
* level. - 4096-bit: High-security (but can be slow).
|
||||
*
|
||||
* 2) ECDH (using secp256r1):
|
||||
* - Classified as a secure elliptic-curve key exchange.
|
||||
* 2) ECDH (using secp256r1): - Classified as a secure elliptic-curve key
|
||||
* exchange.
|
||||
*
|
||||
* 3) X25519:
|
||||
* - A modern and efficient elliptic-curve key exchange protocol.
|
||||
* 3) X25519: - A modern and efficient elliptic-curve key exchange protocol.
|
||||
*
|
||||
* 4) X448:
|
||||
* - Provides a higher security level for key exchange.
|
||||
* 4) X448: - Provides a higher security level for key exchange.
|
||||
*
|
||||
* In addition, the class now includes a nuanced insecure example that
|
||||
* demonstrates:
|
||||
* - Reusing static key pairs instead of generating fresh ephemeral keys.
|
||||
* - Using weak parameters (512-bit DH) in a key exchange.
|
||||
* demonstrates: - Reusing static key pairs instead of generating fresh
|
||||
* ephemeral keys. - Using weak parameters (512-bit DH) in a key exchange.
|
||||
*
|
||||
* The runAllExchanges() method demonstrates generating keys for each algorithm,
|
||||
* deriving shared secrets, and comparing safe vs. insecure practices.
|
||||
@@ -40,7 +35,6 @@ public class KeyExchange {
|
||||
// // Add the BouncyCastle provider to support additional algorithms.
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
//////////////////////////////////////////
|
||||
// 1. Classic DH (Diffie-Hellman)
|
||||
//////////////////////////////////////////
|
||||
@@ -64,8 +58,7 @@ public class KeyExchange {
|
||||
* Generates a deprecated/unsafe Diffie-Hellman key pair using a 512-bit
|
||||
* modulus.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Parent: Classic Diffie-Hellman Key Exchange.
|
||||
* CBOM/SAST Classification: - Parent: Classic Diffie-Hellman Key Exchange.
|
||||
* - 512-bit DH is considered insecure and should be flagged by SAST tools.
|
||||
*
|
||||
* @return A 512-bit (insecure) DH KeyPair.
|
||||
@@ -78,10 +71,10 @@ public class KeyExchange {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a high-security Diffie-Hellman key pair using a 4096-bit modulus.
|
||||
* Generates a high-security Diffie-Hellman key pair using a 4096-bit
|
||||
* modulus.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Parent: Classic Diffie-Hellman Key Exchange.
|
||||
* CBOM/SAST Classification: - Parent: Classic Diffie-Hellman Key Exchange.
|
||||
* - 4096-bit DH offers high security, though it may be slower in practice.
|
||||
*
|
||||
* @return A 4096-bit DH KeyPair.
|
||||
@@ -95,12 +88,11 @@ public class KeyExchange {
|
||||
/**
|
||||
* Derives a shared secret from a DH key pair.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Parent: Classic Diffie-Hellman Key Exchange.
|
||||
* CBOM/SAST Classification: - Parent: Classic Diffie-Hellman Key Exchange.
|
||||
* - Properly deriving the shared secret is secure if using a safe key size.
|
||||
*
|
||||
* @param privateKey The private key of one party.
|
||||
* @param publicKey The public key of the other party.
|
||||
* @param publicKey The public key of the other party.
|
||||
* @return The derived shared secret as a byte array.
|
||||
*/
|
||||
public byte[] deriveDHSecret(PrivateKey privateKey, PublicKey publicKey) throws Exception {
|
||||
@@ -133,12 +125,11 @@ public class KeyExchange {
|
||||
/**
|
||||
* Derives a shared secret using ECDH.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Parent: Elliptic Curve Diffie-Hellman (ECDH).
|
||||
* CBOM/SAST Classification: - Parent: Elliptic Curve Diffie-Hellman (ECDH).
|
||||
* - Secure when using appropriate curves and proper randomness.
|
||||
*
|
||||
* @param privateKey The ECDH private key.
|
||||
* @param publicKey The corresponding public key.
|
||||
* @param publicKey The corresponding public key.
|
||||
* @return The derived ECDH shared secret.
|
||||
*/
|
||||
public byte[] deriveECDHSecret(PrivateKey privateKey, PublicKey publicKey) throws Exception {
|
||||
@@ -171,12 +162,11 @@ public class KeyExchange {
|
||||
/**
|
||||
* Derives a shared secret using the X25519 key agreement.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Parent: Modern Elliptic-Curve Key Exchange.
|
||||
* - X25519 is highly recommended for its security and efficiency.
|
||||
* CBOM/SAST Classification: - Parent: Modern Elliptic-Curve Key Exchange. -
|
||||
* X25519 is highly recommended for its security and efficiency.
|
||||
*
|
||||
* @param privateKey The X25519 private key.
|
||||
* @param publicKey The corresponding public key.
|
||||
* @param publicKey The corresponding public key.
|
||||
* @return The derived X25519 shared secret.
|
||||
*/
|
||||
public byte[] deriveX25519Secret(PrivateKey privateKey, PublicKey publicKey) throws Exception {
|
||||
@@ -209,12 +199,11 @@ public class KeyExchange {
|
||||
/**
|
||||
* Derives a shared secret using the X448 key agreement.
|
||||
*
|
||||
* CBOM/SAST Classification:
|
||||
* - Parent: Modern Elliptic-Curve Key Exchange.
|
||||
* - X448 is considered secure and suitable for high-security applications.
|
||||
* CBOM/SAST Classification: - Parent: Modern Elliptic-Curve Key Exchange. -
|
||||
* X448 is considered secure and suitable for high-security applications.
|
||||
*
|
||||
* @param privateKey The X448 private key.
|
||||
* @param publicKey The corresponding public key.
|
||||
* @param publicKey The corresponding public key.
|
||||
* @return The derived X448 shared secret.
|
||||
*/
|
||||
public byte[] deriveX448Secret(PrivateKey privateKey, PublicKey publicKey) throws Exception {
|
||||
@@ -248,8 +237,8 @@ public class KeyExchange {
|
||||
KeyPair staticDHKeyPair = generateDHDeprecated();
|
||||
// Reusing the same static DH key pair for both parties.
|
||||
byte[] staticDHSecret = deriveDHSecret(staticDHKeyPair.getPrivate(), staticDHKeyPair.getPublic());
|
||||
System.out.println("Static DH (512-bit) shared secret (reused): " +
|
||||
Base64.getEncoder().encodeToString(staticDHSecret));
|
||||
System.out.println("Static DH (512-bit) shared secret (reused): "
|
||||
+ Base64.getEncoder().encodeToString(staticDHSecret));
|
||||
// SAST Note: 512-bit DH is considered insecure and static key reuse prevents
|
||||
// forward secrecy.
|
||||
|
||||
@@ -259,8 +248,8 @@ public class KeyExchange {
|
||||
// Using the same key pair for both sides leads to a shared secret that is
|
||||
// easily derived.
|
||||
byte[] reusedECDHSecret = deriveECDHSecret(reusedECDHKeyPair.getPrivate(), reusedECDHKeyPair.getPublic());
|
||||
System.out.println("Reused ECDH shared secret: " +
|
||||
Base64.getEncoder().encodeToString(reusedECDHSecret));
|
||||
System.out.println("Reused ECDH shared secret: "
|
||||
+ Base64.getEncoder().encodeToString(reusedECDHSecret));
|
||||
// SAST Note: Proper key exchange requires fresh ephemeral keys for each session
|
||||
// to ensure forward secrecy.
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* MACOperation demonstrates various Message Authentication Code (MAC)
|
||||
@@ -20,47 +19,42 @@ import java.util.Base64;
|
||||
*
|
||||
* Flows include:
|
||||
*
|
||||
* 1. Secure HMAC‑SHA2 (HMAC‑SHA256) – a widely accepted MAC.
|
||||
* 2. Secure HMAC‑SHA3 (HMAC‑SHA3-256) – an alternative using the SHA‑3 family.
|
||||
* 3. Secure Poly1305 MAC – using BouncyCastle’s implementation.
|
||||
* 4. Secure GMAC – using AES‑GCM’s authentication tag in a dedicated MAC mode.
|
||||
* 5. Secure KMAC – using KMAC128 (from the SHA‑3 family).
|
||||
* 1. Secure HMAC-SHA2 (HMAC-SHA256) – a widely accepted MAC. 2. Secure
|
||||
* HMAC-SHA3 (HMAC-SHA3-256) – an alternative using the SHA-3 family. 3. Secure
|
||||
* Poly1305 MAC – using BouncyCastle’s implementation. 4. Secure GMAC – using
|
||||
* AES-GCM’s authentication tag in a dedicated MAC mode. 5. Secure KMAC – using
|
||||
* KMAC128 (from the SHA-3 family).
|
||||
*
|
||||
* Insecure examples include:
|
||||
*
|
||||
* 6. Insecure HMAC‑SHA1 – which is deprecated.
|
||||
* 6. Insecure HMAC-SHA1 – which is deprecated.
|
||||
*
|
||||
* Further flows:
|
||||
*
|
||||
* A. processMACOutput: Uses the MAC output directly as key material for AES
|
||||
* encryption.
|
||||
* (Note: This is acceptable only if the MAC is produced by a secure function.)
|
||||
* encryption. (Note: This is acceptable only if the MAC is produced by a secure
|
||||
* function.)
|
||||
*
|
||||
* B. alternativeMACFlow: Uses the MAC output as an identifier that is then
|
||||
* encrypted.
|
||||
*
|
||||
* C. furtherUseMACForKeyDerivation: Uses PBKDF2 to split a MAC output into two
|
||||
* keys,
|
||||
* one for encryption and one for MACing ciphertext.
|
||||
* keys, one for encryption and one for MACing ciphertext.
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - Secure MAC algorithms (HMAC‑SHA256, HMAC‑SHA3-256, Poly1305, GMAC, KMAC128)
|
||||
* are acceptable if used correctly.
|
||||
* - HMAC‑SHA1 is flagged as insecure.
|
||||
* - Using a raw MAC output directly as key material is ambiguous unless the MAC
|
||||
* is produced by a secure KDF.
|
||||
* SAST/CBOM Notes: - Secure MAC algorithms (HMAC-SHA256, HMAC-SHA3-256,
|
||||
* Poly1305, GMAC, KMAC128) are acceptable if used correctly. - HMAC-SHA1 is
|
||||
* flagged as insecure. - Using a raw MAC output directly as key material is
|
||||
* ambiguous unless the MAC is produced by a secure KDF.
|
||||
*/
|
||||
public class MACOperation {
|
||||
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
// ---------- MAC Operations ----------
|
||||
|
||||
/**
|
||||
* Secure MAC using HMAC-SHA256.
|
||||
* SAST: HMAC-SHA256 is widely considered secure.
|
||||
* Secure MAC using HMAC-SHA256. SAST: HMAC-SHA256 is widely considered
|
||||
* secure.
|
||||
*/
|
||||
public byte[] secureHMACSHA256(String message, byte[] key) throws Exception {
|
||||
Mac mac = Mac.getInstance("HmacSHA256", "BC");
|
||||
@@ -70,8 +64,8 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure MAC using HMAC-SHA3-256.
|
||||
* SAST: HMAC-SHA3 is a modern alternative from the SHA-3 family.
|
||||
* Secure MAC using HMAC-SHA3-256. SAST: HMAC-SHA3 is a modern alternative
|
||||
* from the SHA-3 family.
|
||||
*/
|
||||
public byte[] secureHMACSHA3(String message, byte[] key) throws Exception {
|
||||
Mac mac = Mac.getInstance("HmacSHA3-256", "BC");
|
||||
@@ -81,9 +75,8 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure MAC using Poly1305.
|
||||
* SAST: Poly1305 is secure when used with a one-time key from a cipher (e.g.
|
||||
* ChaCha20).
|
||||
* Secure MAC using Poly1305. SAST: Poly1305 is secure when used with a
|
||||
* one-time key from a cipher (e.g. ChaCha20).
|
||||
*/
|
||||
public byte[] securePoly1305(String message, byte[] key) throws Exception {
|
||||
Mac mac = Mac.getInstance("Poly1305", "BC");
|
||||
@@ -93,8 +86,8 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure MAC using GMAC.
|
||||
* SAST: GMAC (the MAC part of AES-GCM) is secure when used correctly.
|
||||
* Secure MAC using GMAC. SAST: GMAC (the MAC part of AES-GCM) is secure
|
||||
* when used correctly.
|
||||
*/
|
||||
public byte[] secureGMAC(String message, byte[] key) throws Exception {
|
||||
// For GMAC, we use the GMac algorithm as provided by BC.
|
||||
@@ -107,8 +100,8 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure MAC using KMAC128.
|
||||
* SAST: KMAC128 is part of the SHA-3 family and is secure when used properly.
|
||||
* Secure MAC using KMAC128. SAST: KMAC128 is part of the SHA-3 family and
|
||||
* is secure when used properly.
|
||||
*/
|
||||
public byte[] secureKMAC(String message, byte[] key) throws Exception {
|
||||
Mac mac = Mac.getInstance("KMAC128", "BC");
|
||||
@@ -118,8 +111,8 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Insecure MAC using HMAC-SHA1.
|
||||
* SAST: HMAC-SHA1 is considered deprecated and weak.
|
||||
* Insecure MAC using HMAC-SHA1. SAST: HMAC-SHA1 is considered deprecated
|
||||
* and weak.
|
||||
*/
|
||||
public byte[] insecureHMACSHA1(String message, byte[] key) throws Exception {
|
||||
Mac mac = Mac.getInstance("HmacSHA1", "BC");
|
||||
@@ -129,12 +122,10 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
// ---------- Further Use of MAC Outputs ----------
|
||||
|
||||
/**
|
||||
* Processes the MAC output by using it as key material for AES encryption.
|
||||
* SAST: Using a raw MAC output as key material is acceptable only if the MAC
|
||||
* was
|
||||
* produced by a secure function; otherwise, this is ambiguous.
|
||||
* SAST: Using a raw MAC output as key material is acceptable only if the
|
||||
* MAC was produced by a secure function; otherwise, this is ambiguous.
|
||||
*
|
||||
* @param macOutput The computed MAC output.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -149,9 +140,9 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative flow: Uses the MAC output as an identifier and then encrypts it.
|
||||
* SAST: Using a MAC as an identifier is common; subsequent encryption must be
|
||||
* secure.
|
||||
* Alternative flow: Uses the MAC output as an identifier and then encrypts
|
||||
* it. SAST: Using a MAC as an identifier is common; subsequent encryption
|
||||
* must be secure.
|
||||
*
|
||||
* @param macOutput The computed MAC output.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -163,10 +154,11 @@ public class MACOperation {
|
||||
|
||||
/**
|
||||
* Further use: Derives two separate keys from the MAC output using PBKDF2,
|
||||
* then uses one key for encryption and one for computing an additional MAC over
|
||||
* the ciphertext.
|
||||
* then uses one key for encryption and one for computing an additional MAC
|
||||
* over the ciphertext.
|
||||
*
|
||||
* SAST: This key-splitting technique is acceptable if PBKDF2 is used securely.
|
||||
* SAST: This key-splitting technique is acceptable if PBKDF2 is used
|
||||
* securely.
|
||||
*
|
||||
* @param macOutput The MAC output to derive keys from.
|
||||
* @throws Exception if key derivation or encryption fails.
|
||||
@@ -202,7 +194,6 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
// ---------- Output/Storage Methods ----------
|
||||
|
||||
/**
|
||||
* Simulates secure storage or transmission of an encrypted MAC output.
|
||||
* SAST: In production, storage and transmission must be protected.
|
||||
@@ -215,8 +206,8 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts data using AES-GCM and simulates secure transmission.
|
||||
* SAST: Uses a securely generated AES key.
|
||||
* Encrypts data using AES-GCM and simulates secure transmission. SAST: Uses
|
||||
* a securely generated AES key.
|
||||
*
|
||||
* @param data The data to encrypt.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -230,10 +221,9 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
// ---------- Helper Methods ----------
|
||||
|
||||
/**
|
||||
* Generates a secure 256-bit AES key.
|
||||
* SAST: Uses a strong RNG for key generation.
|
||||
* Generates a secure 256-bit AES key. SAST: Uses a strong RNG for key
|
||||
* generation.
|
||||
*
|
||||
* @return A SecretKey for AES.
|
||||
* @throws NoSuchAlgorithmException if AES is unsupported.
|
||||
@@ -245,8 +235,8 @@ public class MACOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random salt of the specified length using SecureRandom.
|
||||
* SAST: Salting is essential for secure key derivation.
|
||||
* Generates a random salt of the specified length using SecureRandom. SAST:
|
||||
* Salting is essential for secure key derivation.
|
||||
*
|
||||
* @param length The salt length.
|
||||
* @return A byte array representing the salt.
|
||||
|
||||
@@ -15,7 +15,6 @@ public class Nonce {
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider()); // Ensure BouncyCastle is available
|
||||
// }
|
||||
|
||||
/**
|
||||
* Simple Case: Generates a secure nonce and uses it in HMAC.
|
||||
*/
|
||||
|
||||
@@ -10,28 +10,23 @@ import javax.crypto.KeyGenerator;
|
||||
* PrngTest demonstrates various approaches for generating random data using
|
||||
* PRNG/RNG APIs.
|
||||
*
|
||||
* It covers:
|
||||
* 1) Secure random generation using SecureRandom (default and
|
||||
* getInstanceStrong).
|
||||
* 2) Insecure random generation using java.util.Random.
|
||||
* 3) Flawed PRNG usage by setting a fixed seed.
|
||||
* 4) Dynamic PRNG selection based on configuration.
|
||||
* 5) Usage of random data as nonces/IVs in symmetric encryption.
|
||||
* It covers: 1) Secure random generation using SecureRandom (default and
|
||||
* getInstanceStrong). 2) Insecure random generation using java.util.Random. 3)
|
||||
* Flawed PRNG usage by setting a fixed seed. 4) Dynamic PRNG selection based on
|
||||
* configuration. 5) Usage of random data as nonces/IVs in symmetric encryption.
|
||||
*
|
||||
* SAST/CBOM Notes:
|
||||
* - SecureRandom (and SecureRandom.getInstanceStrong) are recommended.
|
||||
* - java.util.Random is not suitable for cryptographic purposes.
|
||||
* - Re-seeding or using a fixed seed with SecureRandom makes it predictable.
|
||||
* - IVs and nonces must be unique for each operation; reusing fixed values is
|
||||
* SAST/CBOM Notes: - SecureRandom (and SecureRandom.getInstanceStrong) are
|
||||
* recommended. - java.util.Random is not suitable for cryptographic purposes. -
|
||||
* Re-seeding or using a fixed seed with SecureRandom makes it predictable. -
|
||||
* IVs and nonces must be unique for each operation; reusing fixed values is
|
||||
* insecure.
|
||||
*/
|
||||
public class PrngTest {
|
||||
|
||||
// ---------- Secure Random Generation ----------
|
||||
|
||||
/**
|
||||
* Generates random bytes using the default SecureRandom.
|
||||
* SAST: SecureRandom is recommended for cryptographically secure random data.
|
||||
* Generates random bytes using the default SecureRandom. SAST: SecureRandom
|
||||
* is recommended for cryptographically secure random data.
|
||||
*
|
||||
* @param numBytes Number of bytes to generate.
|
||||
* @return A byte array of random data.
|
||||
@@ -44,8 +39,8 @@ public class PrngTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates random bytes using SecureRandom.getInstanceStrong().
|
||||
* SAST: getInstanceStrong() returns a strong RNG (may block in some
|
||||
* Generates random bytes using SecureRandom.getInstanceStrong(). SAST:
|
||||
* getInstanceStrong() returns a strong RNG (may block in some
|
||||
* environments).
|
||||
*
|
||||
* @param numBytes Number of bytes to generate.
|
||||
@@ -60,11 +55,9 @@ public class PrngTest {
|
||||
}
|
||||
|
||||
// ---------- Insecure Random Generation ----------
|
||||
|
||||
/**
|
||||
* Generates random bytes using java.util.Random.
|
||||
* SAST: java.util.Random is predictable and insecure for cryptographic
|
||||
* purposes.
|
||||
* Generates random bytes using java.util.Random. SAST: java.util.Random is
|
||||
* predictable and insecure for cryptographic purposes.
|
||||
*
|
||||
* @param numBytes Number of bytes to generate.
|
||||
* @return A byte array of random data.
|
||||
@@ -77,8 +70,8 @@ public class PrngTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates random bytes using SecureRandom with a fixed seed.
|
||||
* SAST: Fixed seeding makes SecureRandom predictable and insecure.
|
||||
* Generates random bytes using SecureRandom with a fixed seed. SAST: Fixed
|
||||
* seeding makes SecureRandom predictable and insecure.
|
||||
*
|
||||
* @param numBytes Number of bytes to generate.
|
||||
* @return A byte array of predictable random data.
|
||||
@@ -93,15 +86,14 @@ public class PrngTest {
|
||||
}
|
||||
|
||||
// ---------- Dynamic PRNG Selection ----------
|
||||
|
||||
/**
|
||||
* Dynamically selects a PRNG algorithm based on a configuration property.
|
||||
* If the algorithm is unknown, falls back to java.util.Random (insecure).
|
||||
* SAST: Dynamic selection may introduce risk if an insecure RNG is chosen.
|
||||
*
|
||||
* @param algorithmName The PRNG algorithm name (e.g. "SHA1PRNG",
|
||||
* "NativePRNGNonBlocking", "getInstanceStrong").
|
||||
* @param numBytes Number of bytes to generate.
|
||||
* "NativePRNGNonBlocking", "getInstanceStrong").
|
||||
* @param numBytes Number of bytes to generate.
|
||||
* @return A byte array of random data.
|
||||
* @throws NoSuchAlgorithmException if the algorithm is not available.
|
||||
*/
|
||||
@@ -128,10 +120,9 @@ public class PrngTest {
|
||||
|
||||
// ---------- Usage Examples: Nonce/IV Generation for Symmetric Encryption
|
||||
// ----------
|
||||
|
||||
/**
|
||||
* Demonstrates secure generation of an IV for AES-GCM encryption.
|
||||
* SAST: A unique, random IV is required for each encryption operation.
|
||||
* Demonstrates secure generation of an IV for AES-GCM encryption. SAST: A
|
||||
* unique, random IV is required for each encryption operation.
|
||||
*
|
||||
* @return A 12-byte IV.
|
||||
*/
|
||||
@@ -140,8 +131,8 @@ public class PrngTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Demonstrates insecure use of a fixed IV for AES-GCM encryption.
|
||||
* SAST: Reusing a fixed IV in AES-GCM compromises security.
|
||||
* Demonstrates insecure use of a fixed IV for AES-GCM encryption. SAST:
|
||||
* Reusing a fixed IV in AES-GCM compromises security.
|
||||
*
|
||||
* @return A fixed 12-byte IV (all zeros).
|
||||
*/
|
||||
@@ -150,10 +141,9 @@ public class PrngTest {
|
||||
}
|
||||
|
||||
// ---------- Example: Using PRNG for Key Generation ----------
|
||||
|
||||
/**
|
||||
* Generates a secure 256-bit AES key using SecureRandom.
|
||||
* SAST: Strong key generation is critical for symmetric cryptography.
|
||||
* Generates a secure 256-bit AES key using SecureRandom. SAST: Strong key
|
||||
* generation is critical for symmetric cryptography.
|
||||
*
|
||||
* @return A new AES SecretKey.
|
||||
* @throws Exception if key generation fails.
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class demonstrates cryptographic flows combining signing, encryption,
|
||||
@@ -18,26 +17,21 @@ import java.util.Arrays;
|
||||
* It intentionally includes both safe and unsafe patterns so that a SAST tool
|
||||
* can detect:
|
||||
*
|
||||
* 1. **Sign then Encrypt (Unsafe)**
|
||||
* - Signs the plaintext and encrypts only the signature, leaving the plaintext
|
||||
* in cleartext.
|
||||
* - *Issue:* The message is exposed, which could lead to replay or modification
|
||||
* attacks.
|
||||
* 1. **Sign then Encrypt (Unsafe)** - Signs the plaintext and encrypts only the
|
||||
* signature, leaving the plaintext in cleartext. - *Issue:* The message is
|
||||
* exposed, which could lead to replay or modification attacks.
|
||||
*
|
||||
* 2. **Encrypt then Sign (Safe with caveats)**
|
||||
* - Encrypts the plaintext and then signs the ciphertext.
|
||||
* - *Caveat:* The signature is in the clear; metadata (e.g. ciphertext length)
|
||||
* may be exposed.
|
||||
* 2. **Encrypt then Sign (Safe with caveats)** - Encrypts the plaintext and
|
||||
* then signs the ciphertext. - *Caveat:* The signature is in the clear;
|
||||
* metadata (e.g. ciphertext length) may be exposed.
|
||||
*
|
||||
* 3. **MAC then Encrypt (Unsafe)**
|
||||
* - Computes a MAC on the plaintext and appends it before encryption.
|
||||
* - *Issue:* Operating on plaintext for MAC generation can leak information and
|
||||
* is discouraged.
|
||||
* 3. **MAC then Encrypt (Unsafe)** - Computes a MAC on the plaintext and
|
||||
* appends it before encryption. - *Issue:* Operating on plaintext for MAC
|
||||
* generation can leak information and is discouraged.
|
||||
*
|
||||
* 4. **Encrypt then MAC (Safe)**
|
||||
* - Encrypts the plaintext and computes a MAC over the ciphertext.
|
||||
* - *Benefit:* Provides a robust authenticated encryption construction when not
|
||||
* using an AEAD cipher.
|
||||
* 4. **Encrypt then MAC (Safe)** - Encrypts the plaintext and computes a MAC
|
||||
* over the ciphertext. - *Benefit:* Provides a robust authenticated encryption
|
||||
* construction when not using an AEAD cipher.
|
||||
*
|
||||
* Note: AES/GCM already provides authentication, so adding an external MAC is
|
||||
* redundant.
|
||||
@@ -49,7 +43,6 @@ public class SignEncryptCombinations {
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Key Generation for ECDSA on secp256r1
|
||||
///////////////////////////////////////////////
|
||||
@@ -92,8 +85,8 @@ public class SignEncryptCombinations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts data using AES-GCM with a 12-byte IV and a 128-bit tag.
|
||||
* Returns the concatenation of IV and ciphertext.
|
||||
* Encrypts data using AES-GCM with a 12-byte IV and a 128-bit tag. Returns
|
||||
* the concatenation of IV and ciphertext.
|
||||
*/
|
||||
public byte[] encryptAESGCM(SecretKey key, byte[] plaintext) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
@@ -176,14 +169,14 @@ public class SignEncryptCombinations {
|
||||
*
|
||||
* <p>
|
||||
* **Benefit:** The plaintext is fully encrypted and remains confidential.
|
||||
* **Caveat:** The signature is transmitted in the clear. Although this does not
|
||||
* compromise
|
||||
* the message, it might reveal metadata (like ciphertext length).
|
||||
* **Caveat:** The signature is transmitted in the clear. Although this does
|
||||
* not compromise the message, it might reveal metadata (like ciphertext
|
||||
* length).
|
||||
* </p>
|
||||
*
|
||||
* @param encryptionKey AES key for encryption.
|
||||
* @param signingKey ECDSA private key for signing.
|
||||
* @param data The plaintext message.
|
||||
* @param signingKey ECDSA private key for signing.
|
||||
* @param data The plaintext message.
|
||||
* @return The concatenation of the ciphertext and its signature.
|
||||
*/
|
||||
public byte[] encryptThenSign(SecretKey encryptionKey, PrivateKey signingKey, byte[] data) throws Exception {
|
||||
@@ -200,20 +193,18 @@ public class SignEncryptCombinations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts and verifies the signature from the combined ciphertext-signature
|
||||
* bundle,
|
||||
* then decrypts the ciphertext.
|
||||
* Extracts and verifies the signature from the combined
|
||||
* ciphertext-signature bundle, then decrypts the ciphertext.
|
||||
*
|
||||
* <p>
|
||||
* **Issue:** Here we assume a fixed signature length (70 bytes). In production,
|
||||
* the signature length
|
||||
* should be explicitly stored. Hard-coding a length is an unsafe pattern and
|
||||
* may trigger SAST warnings.
|
||||
* **Issue:** Here we assume a fixed signature length (70 bytes). In
|
||||
* production, the signature length should be explicitly stored. Hard-coding
|
||||
* a length is an unsafe pattern and may trigger SAST warnings.
|
||||
* </p>
|
||||
*
|
||||
* @param verifyingKey ECDSA public key for signature verification.
|
||||
* @param verifyingKey ECDSA public key for signature verification.
|
||||
* @param encryptionKey AES key for decryption.
|
||||
* @param combined The combined ciphertext and signature.
|
||||
* @param combined The combined ciphertext and signature.
|
||||
* @return The decrypted plaintext message.
|
||||
*/
|
||||
public byte[] verifyThenDecrypt(PublicKey verifyingKey, SecretKey encryptionKey, byte[] combined) throws Exception {
|
||||
@@ -268,8 +259,8 @@ public class SignEncryptCombinations {
|
||||
/**
|
||||
* Decrypts the combined data and verifies the MAC.
|
||||
*
|
||||
* @param macKey AES key used as the HMAC key.
|
||||
* @param encKey AES key for decryption.
|
||||
* @param macKey AES key used as the HMAC key.
|
||||
* @param encKey AES key for decryption.
|
||||
* @param ciphertext The encrypted bundle containing plaintext and MAC.
|
||||
* @return true if the MAC is valid; false otherwise.
|
||||
*/
|
||||
@@ -289,14 +280,13 @@ public class SignEncryptCombinations {
|
||||
* ciphertext.
|
||||
*
|
||||
* <p>
|
||||
* **Benefit:** This "encrypt-then-MAC" construction ensures that the ciphertext
|
||||
* is both confidential
|
||||
* and tamper-evident.
|
||||
* **Benefit:** This "encrypt-then-MAC" construction ensures that the
|
||||
* ciphertext is both confidential and tamper-evident.
|
||||
* </p>
|
||||
*
|
||||
* @param encKey AES key for encryption.
|
||||
* @param macKey AES key used as the HMAC key.
|
||||
* @param data The plaintext message.
|
||||
* @param data The plaintext message.
|
||||
* @return The concatenation of ciphertext and MAC.
|
||||
*/
|
||||
public byte[] encryptThenMac(SecretKey encKey, SecretKey macKey, byte[] data) throws Exception {
|
||||
@@ -314,8 +304,8 @@ public class SignEncryptCombinations {
|
||||
/**
|
||||
* Verifies the MAC and then decrypts the ciphertext.
|
||||
*
|
||||
* @param encKey AES key for decryption.
|
||||
* @param macKey AES key used as the HMAC key.
|
||||
* @param encKey AES key for decryption.
|
||||
* @param macKey AES key used as the HMAC key.
|
||||
* @param combined The combined ciphertext and MAC.
|
||||
* @return The decrypted plaintext message.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Base64;
|
||||
@@ -10,32 +9,27 @@ import java.util.Properties;
|
||||
/**
|
||||
* Demonstrates various digital signature operations:
|
||||
*
|
||||
* 1) RSA-PSS (modern, safer)
|
||||
* - CBOM/SAST: Classified as a Modern Digital Signature scheme using RSA-PSS.
|
||||
* RSA-PSS with SHA-256 is recommended.
|
||||
* 1) RSA-PSS (modern, safer) - CBOM/SAST: Classified as a Modern Digital
|
||||
* Signature scheme using RSA-PSS. RSA-PSS with SHA-256 is recommended.
|
||||
*
|
||||
* 2) ECDSA with secp256r1
|
||||
* - CBOM/SAST: Classified as an Elliptic Curve Digital Signature Algorithm.
|
||||
* Secure when used with a strong curve and proper randomness.
|
||||
* 2) ECDSA with secp256r1 - CBOM/SAST: Classified as an Elliptic Curve Digital
|
||||
* Signature Algorithm. Secure when used with a strong curve and proper
|
||||
* randomness.
|
||||
*
|
||||
* 3) Ed25519 (RFC 8032)
|
||||
* - CBOM/SAST: Classified as a modern, high-performance signature scheme.
|
||||
* 3) Ed25519 (RFC 8032) - CBOM/SAST: Classified as a modern, high-performance
|
||||
* signature scheme.
|
||||
*
|
||||
* 4) SHA1withRSA (deprecated/unsafe example)
|
||||
* - CBOM/SAST: Classified as a legacy digital signature scheme.
|
||||
* SHA-1 and 1024-bit RSA are deprecated.
|
||||
* 4) SHA1withRSA (deprecated/unsafe example) - CBOM/SAST: Classified as a
|
||||
* legacy digital signature scheme. SHA-1 and 1024-bit RSA are deprecated.
|
||||
*
|
||||
* Additional nuanced examples:
|
||||
*
|
||||
* - Signing and verifying an empty message.
|
||||
* - Signing data with non-ASCII characters.
|
||||
* - Demonstrating signature tampering and its detection.
|
||||
* - A dynamic (runtime-selected) signature algorithm scenario ("known
|
||||
* unknown").
|
||||
* - Signing and verifying an empty message. - Signing data with non-ASCII
|
||||
* characters. - Demonstrating signature tampering and its detection. - A
|
||||
* dynamic (runtime-selected) signature algorithm scenario ("known unknown").
|
||||
*
|
||||
* Requirements:
|
||||
* - BouncyCastle for ECDSA, Ed25519, and RSA-PSS (if needed).
|
||||
* - Java 11+ for native Ed25519 support or using BC for older versions.
|
||||
* Requirements: - BouncyCastle for ECDSA, Ed25519, and RSA-PSS (if needed). -
|
||||
* Java 11+ for native Ed25519 support or using BC for older versions.
|
||||
*/
|
||||
public class SignatureOperation {
|
||||
|
||||
@@ -43,7 +37,6 @@ public class SignatureOperation {
|
||||
// // Register the BouncyCastle provider.
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
///////////////////////////////////////
|
||||
// 1. RSA-PSS (Recommended)
|
||||
///////////////////////////////////////
|
||||
@@ -64,8 +57,7 @@ public class SignatureOperation {
|
||||
/**
|
||||
* Sign data using RSA-PSS with SHA-256.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Parent: Modern Digital Signature (RSA-PSS).
|
||||
* CBOM/SAST Notes: - Parent: Modern Digital Signature (RSA-PSS).
|
||||
*/
|
||||
public byte[] signRSAPSS(PrivateKey privateKey, byte[] data) throws Exception {
|
||||
Signature signature = Signature.getInstance("SHA256withRSAandMGF1");
|
||||
@@ -77,8 +69,7 @@ public class SignatureOperation {
|
||||
/**
|
||||
* Verify data using RSA-PSS with SHA-256.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Parent: Modern Digital Signature (RSA-PSS).
|
||||
* CBOM/SAST Notes: - Parent: Modern Digital Signature (RSA-PSS).
|
||||
*/
|
||||
public boolean verifyRSAPSS(PublicKey publicKey, byte[] data, byte[] sigBytes) throws Exception {
|
||||
Signature signature = Signature.getInstance("SHA256withRSAandMGF1");
|
||||
@@ -106,8 +97,7 @@ public class SignatureOperation {
|
||||
/**
|
||||
* Sign data using ECDSA with SHA-256.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Parent: Elliptic Curve Digital Signature.
|
||||
* CBOM/SAST Notes: - Parent: Elliptic Curve Digital Signature.
|
||||
*/
|
||||
public byte[] signECDSA(PrivateKey privateKey, byte[] data) throws Exception {
|
||||
Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
|
||||
@@ -119,8 +109,7 @@ public class SignatureOperation {
|
||||
/**
|
||||
* Verify data using ECDSA with SHA-256.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Parent: Elliptic Curve Digital Signature.
|
||||
* CBOM/SAST Notes: - Parent: Elliptic Curve Digital Signature.
|
||||
*/
|
||||
public boolean verifyECDSA(PublicKey publicKey, byte[] data, byte[] sigBytes) throws Exception {
|
||||
Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
|
||||
@@ -147,8 +136,7 @@ public class SignatureOperation {
|
||||
/**
|
||||
* Sign data using Ed25519.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Parent: Modern Digital Signature (EdDSA).
|
||||
* CBOM/SAST Notes: - Parent: Modern Digital Signature (EdDSA).
|
||||
*/
|
||||
public byte[] signEd25519(PrivateKey privateKey, byte[] data) throws Exception {
|
||||
Signature signature = Signature.getInstance("Ed25519", "BC");
|
||||
@@ -160,8 +148,7 @@ public class SignatureOperation {
|
||||
/**
|
||||
* Verify data using Ed25519.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Parent: Modern Digital Signature (EdDSA).
|
||||
* CBOM/SAST Notes: - Parent: Modern Digital Signature (EdDSA).
|
||||
*/
|
||||
public boolean verifyEd25519(PublicKey publicKey, byte[] data, byte[] sigBytes) throws Exception {
|
||||
Signature signature = Signature.getInstance("Ed25519", "BC");
|
||||
@@ -191,9 +178,8 @@ public class SignatureOperation {
|
||||
/**
|
||||
* Sign data using SHA1withRSA.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Parent: Legacy Digital Signature.
|
||||
* - SHA-1 is deprecated and RSA with 1024 bits is considered weak.
|
||||
* CBOM/SAST Notes: - Parent: Legacy Digital Signature. - SHA-1 is
|
||||
* deprecated and RSA with 1024 bits is considered weak.
|
||||
*/
|
||||
public byte[] signSHA1withRSA(PrivateKey privateKey, byte[] data) throws Exception {
|
||||
Signature signature = Signature.getInstance("SHA1withRSA");
|
||||
@@ -205,9 +191,8 @@ public class SignatureOperation {
|
||||
/**
|
||||
* Verify data using SHA1withRSA.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Parent: Legacy Digital Signature.
|
||||
* - Verification of SHA1withRSA is insecure.
|
||||
* CBOM/SAST Notes: - Parent: Legacy Digital Signature. - Verification of
|
||||
* SHA1withRSA is insecure.
|
||||
*/
|
||||
public boolean verifySHA1withRSA(PublicKey publicKey, byte[] data, byte[] sigBytes) throws Exception {
|
||||
Signature signature = Signature.getInstance("SHA1withRSA");
|
||||
@@ -239,9 +224,8 @@ public class SignatureOperation {
|
||||
* Demonstrates that even a slight tampering with the signature will cause
|
||||
* verification to fail.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Edge Case: Signature integrity is critical. Any change—even a single
|
||||
* byte—should invalidate the signature.
|
||||
* CBOM/SAST Notes: - Edge Case: Signature integrity is critical. Any
|
||||
* change-even a single byte-should invalidate the signature.
|
||||
*/
|
||||
public void tamperSignatureEdgeCase() throws Exception {
|
||||
byte[] message = "Important Message".getBytes();
|
||||
@@ -257,14 +241,13 @@ public class SignatureOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Demonstrates dynamic signature algorithm selection.
|
||||
* This is a "known unknown" scenario where the algorithm is chosen at runtime
|
||||
* based on configuration. If the configuration is compromised or misconfigured,
|
||||
* an insecure algorithm might be selected.
|
||||
* Demonstrates dynamic signature algorithm selection. This is a "known
|
||||
* unknown" scenario where the algorithm is chosen at runtime based on
|
||||
* configuration. If the configuration is compromised or misconfigured, an
|
||||
* insecure algorithm might be selected.
|
||||
*
|
||||
* CBOM/SAST Notes:
|
||||
* - Known Unknown: Dynamic configuration introduces ambiguity and risk.
|
||||
* - Ensure that fallback defaults are secure.
|
||||
* CBOM/SAST Notes: - Known Unknown: Dynamic configuration introduces
|
||||
* ambiguity and risk. - Ensure that fallback defaults are secure.
|
||||
*/
|
||||
public void dynamicSignatureSelectionDemo() throws Exception {
|
||||
// Simulate loading a configuration.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.security.*;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
@@ -19,39 +18,31 @@ import java.util.Base64;
|
||||
|
||||
/**
|
||||
* SymmetricAlgorithmTest demonstrates various symmetric encryption flows and
|
||||
* key derivation
|
||||
* scenarios that can be analyzed by SAST tools.
|
||||
* key derivation scenarios that can be analyzed by SAST tools.
|
||||
*
|
||||
* It includes:
|
||||
* 1) AES-GCM encryption with random nonce (secure).
|
||||
* 2) AES-GCM encryption with fixed nonce (insecure).
|
||||
* 3) AES-CBC encryption with random IV (secure).
|
||||
* 4) AES-ECB encryption (insecure).
|
||||
* 5) RC4 encryption (insecure).
|
||||
* 6) DES and TripleDES encryption (insecure/weak).
|
||||
* 7) ChaCha20 encryption (secure, if available).
|
||||
* 8) KMAC-based key derivation used to derive a key for AES encryption.
|
||||
* 9) Dynamic symmetric encryption selection based on configuration.
|
||||
* It includes: 1) AES-GCM encryption with random nonce (secure). 2) AES-GCM
|
||||
* encryption with fixed nonce (insecure). 3) AES-CBC encryption with random IV
|
||||
* (secure). 4) AES-ECB encryption (insecure). 5) RC4 encryption (insecure). 6)
|
||||
* DES and TripleDES encryption (insecure/weak). 7) ChaCha20 encryption (secure,
|
||||
* if available). 8) KMAC-based key derivation used to derive a key for AES
|
||||
* encryption. 9) Dynamic symmetric encryption selection based on configuration.
|
||||
* 10) Further use: deriving two keys from symmetric key material via PBKDF2.
|
||||
*
|
||||
* SAST/CBOM notes:
|
||||
* - Nonce/IV reuse (e.g., fixed nonce) must be flagged.
|
||||
* - Insecure algorithms (RC4, DES, TripleDES, AES/ECB) are marked as unsafe.
|
||||
* - Dynamic selection may lead to insecure fallback if misconfigured.
|
||||
* SAST/CBOM notes: - Nonce/IV reuse (e.g., fixed nonce) must be flagged. -
|
||||
* Insecure algorithms (RC4, DES, TripleDES, AES/ECB) are marked as unsafe. -
|
||||
* Dynamic selection may lead to insecure fallback if misconfigured.
|
||||
*/
|
||||
public class SymmetricAlgorithm {
|
||||
|
||||
// static {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
// ---------- Secure Symmetric Encryption Flows ----------
|
||||
|
||||
/**
|
||||
* AES-GCM encryption using a 12-byte random nonce.
|
||||
* SAST: AES-GCM is secure when a unique nonce is used per encryption.
|
||||
* AES-GCM encryption using a 12-byte random nonce. SAST: AES-GCM is secure
|
||||
* when a unique nonce is used per encryption.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The IV prepended to the ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -70,11 +61,10 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* AES-GCM encryption using a fixed (constant) nonce.
|
||||
* SAST: Fixed nonce reuse in AES-GCM is insecure as it destroys
|
||||
* confidentiality.
|
||||
* AES-GCM encryption using a fixed (constant) nonce. SAST: Fixed nonce
|
||||
* reuse in AES-GCM is insecure as it destroys confidentiality.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The fixed IV prepended to the ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -92,10 +82,10 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* AES-CBC encryption using a random IV.
|
||||
* SAST: AES-CBC is secure if IVs are random and not reused.
|
||||
* AES-CBC encryption using a random IV. SAST: AES-CBC is secure if IVs are
|
||||
* random and not reused.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The IV prepended to the ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -114,10 +104,10 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* AES-ECB encryption.
|
||||
* SAST: ECB mode is insecure as it does not use an IV, revealing data patterns.
|
||||
* AES-ECB encryption. SAST: ECB mode is insecure as it does not use an IV,
|
||||
* revealing data patterns.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -129,12 +119,10 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
// ---------- Other Symmetric Algorithms ----------
|
||||
|
||||
/**
|
||||
* RC4 encryption.
|
||||
* SAST: RC4 is deprecated due to vulnerabilities.
|
||||
* RC4 encryption. SAST: RC4 is deprecated due to vulnerabilities.
|
||||
*
|
||||
* @param key The RC4 key.
|
||||
* @param key The RC4 key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -146,10 +134,10 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* DES encryption.
|
||||
* SAST: DES is insecure due to its 56-bit effective key size.
|
||||
* DES encryption. SAST: DES is insecure due to its 56-bit effective key
|
||||
* size.
|
||||
*
|
||||
* @param key The DES key.
|
||||
* @param key The DES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The IV prepended to the ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -168,10 +156,10 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* TripleDES (DESede) encryption.
|
||||
* SAST: TripleDES is weak by modern standards and is deprecated.
|
||||
* TripleDES (DESede) encryption. SAST: TripleDES is weak by modern
|
||||
* standards and is deprecated.
|
||||
*
|
||||
* @param key The TripleDES key.
|
||||
* @param key The TripleDES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The IV prepended to the ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -190,10 +178,10 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* ChaCha20 encryption.
|
||||
* SAST: ChaCha20 is considered secure and is a modern alternative to AES.
|
||||
* ChaCha20 encryption. SAST: ChaCha20 is considered secure and is a modern
|
||||
* alternative to AES.
|
||||
*
|
||||
* @param key The ChaCha20 key.
|
||||
* @param key The ChaCha20 key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The nonce prepended to the ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -215,10 +203,10 @@ public class SymmetricAlgorithm {
|
||||
* KMAC-based flow: Uses KMAC128 to derive key material for AES encryption.
|
||||
* SAST: KMAC128 is secure as part of the SHA-3 family when used correctly.
|
||||
*
|
||||
* @param key The KMAC key.
|
||||
* @param key The KMAC key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext (with IV) resulting from encryption with a derived
|
||||
* key.
|
||||
* key.
|
||||
* @throws Exception if encryption fails.
|
||||
*/
|
||||
public byte[] kmacEncryptFlow(SecretKey key, byte[] plaintext) throws Exception {
|
||||
@@ -240,17 +228,15 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
// ---------- Dynamic Algorithm Selection ----------
|
||||
|
||||
/**
|
||||
* Dynamically selects a symmetric encryption algorithm based on a configuration
|
||||
* property.
|
||||
* If the algorithm is unknown or ambiguous, falls back to an insecure default
|
||||
* (AES/ECB).
|
||||
* Dynamically selects a symmetric encryption algorithm based on a
|
||||
* configuration property. If the algorithm is unknown or ambiguous, falls
|
||||
* back to an insecure default (AES/ECB).
|
||||
*
|
||||
* SAST: Dynamic selection introduces a known unknown risk.
|
||||
*
|
||||
* @param algorithm The algorithm name from configuration.
|
||||
* @param key The symmetric key.
|
||||
* @param key The symmetric key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -273,10 +259,9 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
// ---------- Further Use of Symmetric Keys ----------
|
||||
|
||||
/**
|
||||
* Derives a key from an input key by simple truncation.
|
||||
* SAST: This approach is ambiguous; a proper KDF should be used.
|
||||
* Derives a key from an input key by simple truncation. SAST: This approach
|
||||
* is ambiguous; a proper KDF should be used.
|
||||
*
|
||||
* @param key The input symmetric key.
|
||||
* @return A derived 128-bit key.
|
||||
@@ -288,10 +273,10 @@ public class SymmetricAlgorithm {
|
||||
|
||||
/**
|
||||
* Further use: Derives two separate keys from a symmetric key using PBKDF2,
|
||||
* then uses one key for encryption and one for MACing ciphertext.
|
||||
* SAST: This key-splitting approach is acceptable if PBKDF2 is used securely.
|
||||
* then uses one key for encryption and one for MACing ciphertext. SAST:
|
||||
* This key-splitting approach is acceptable if PBKDF2 is used securely.
|
||||
*
|
||||
* @param key The input key material.
|
||||
* @param key The input key material.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The concatenated ciphertext and its MAC.
|
||||
* @throws Exception if key derivation or encryption fails.
|
||||
@@ -325,8 +310,8 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the encrypted output.
|
||||
* SAST: In production, secure storage/transmission is required.
|
||||
* Stores the encrypted output. SAST: In production, secure
|
||||
* storage/transmission is required.
|
||||
*
|
||||
* @param output The output to store.
|
||||
*/
|
||||
@@ -335,10 +320,9 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
// ---------- Helper Methods ----------
|
||||
|
||||
/**
|
||||
* Generates a secure 256-bit AES key.
|
||||
* SAST: Uses a strong RNG for key generation.
|
||||
* Generates a secure 256-bit AES key. SAST: Uses a strong RNG for key
|
||||
* generation.
|
||||
*
|
||||
* @return A new AES SecretKey.
|
||||
* @throws Exception if key generation fails.
|
||||
@@ -350,8 +334,8 @@ public class SymmetricAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random salt of the specified length using SecureRandom.
|
||||
* SAST: Salting is essential for secure key derivation.
|
||||
* Generates a random salt of the specified length using SecureRandom. SAST:
|
||||
* Salting is essential for secure key derivation.
|
||||
*
|
||||
* @param length The salt length.
|
||||
* @return A byte array representing the salt.
|
||||
|
||||
@@ -1,33 +1,28 @@
|
||||
package com.example.crypto.algorithms;
|
||||
|
||||
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* SymmetricModesTest demonstrates the use of advanced cipher modes for
|
||||
* symmetric encryption:
|
||||
*
|
||||
* 1. AES/KWP/NoPadding: Uses AES Key Wrap with Padding (KWP) to securely wrap
|
||||
* (encrypt) a key.
|
||||
* - Secure usage: Uses a randomly generated wrapping key.
|
||||
* (encrypt) a key. - Secure usage: Uses a randomly generated wrapping key.
|
||||
*
|
||||
* 2. AES/OFB8/NoPadding: Uses AES in Output Feedback mode with an 8-bit
|
||||
* feedback size.
|
||||
* - Secure usage: Uses a random IV for each encryption.
|
||||
* - Insecure usage: Using a fixed IV (or nonce) in OFB mode compromises
|
||||
* feedback size. - Secure usage: Uses a random IV for each encryption. -
|
||||
* Insecure usage: Using a fixed IV (or nonce) in OFB mode compromises
|
||||
* confidentiality.
|
||||
*
|
||||
* In production, algorithm parameters (such as mode, padding, and IV
|
||||
* generation) should be
|
||||
* externalized via configuration files to support crypto agility.
|
||||
* generation) should be externalized via configuration files to support crypto
|
||||
* agility.
|
||||
*/
|
||||
public class SymmetricModesTest {
|
||||
|
||||
@@ -35,18 +30,15 @@ public class SymmetricModesTest {
|
||||
// // Register BouncyCastle provider for additional cipher modes.
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
// }
|
||||
|
||||
// ---------------------------
|
||||
// AES/KWP/NoPadding Example
|
||||
// ---------------------------
|
||||
|
||||
/**
|
||||
* Securely wraps a target AES key using AES/KWP/NoPadding.
|
||||
*
|
||||
* Best Practice:
|
||||
* - The wrapping key must be generated randomly.
|
||||
* - AES/KWP provides key wrapping with padding, suitable for keys whose lengths
|
||||
* are not multiples of the block size.
|
||||
* Best Practice: - The wrapping key must be generated randomly. - AES/KWP
|
||||
* provides key wrapping with padding, suitable for keys whose lengths are
|
||||
* not multiples of the block size.
|
||||
*
|
||||
* @return The Base64-encoded wrapped key.
|
||||
* @throws Exception if an error occurs during key wrapping.
|
||||
@@ -72,15 +64,13 @@ public class SymmetricModesTest {
|
||||
// ---------------------------
|
||||
// AES/OFB8/NoPadding Examples
|
||||
// ---------------------------
|
||||
|
||||
/**
|
||||
* Securely encrypts plaintext using AES in OFB mode with an 8-bit feedback size
|
||||
* (AES/OFB8/NoPadding).
|
||||
* Securely encrypts plaintext using AES in OFB mode with an 8-bit feedback
|
||||
* size (AES/OFB8/NoPadding).
|
||||
*
|
||||
* Best Practice:
|
||||
* - Use a fresh, random IV for each encryption operation.
|
||||
* Best Practice: - Use a fresh, random IV for each encryption operation.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext (Base64-encoded) with the IV prepended.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -100,15 +90,13 @@ public class SymmetricModesTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Insecurely encrypts plaintext using AES in OFB mode with an 8-bit feedback
|
||||
* size (AES/OFB8/NoPadding)
|
||||
* by using a fixed IV.
|
||||
* Insecurely encrypts plaintext using AES in OFB mode with an 8-bit
|
||||
* feedback size (AES/OFB8/NoPadding) by using a fixed IV.
|
||||
*
|
||||
* Best Practice Violation:
|
||||
* - Using a fixed IV (or nonce) with any encryption mode (including OFB)
|
||||
* compromises the cipher's security.
|
||||
* Best Practice Violation: - Using a fixed IV (or nonce) with any
|
||||
* encryption mode (including OFB) compromises the cipher's security.
|
||||
*
|
||||
* @param key The AES key.
|
||||
* @param key The AES key.
|
||||
* @param plaintext The plaintext to encrypt.
|
||||
* @return The ciphertext (Base64-encoded) with the fixed IV prepended.
|
||||
* @throws Exception if encryption fails.
|
||||
@@ -129,7 +117,6 @@ public class SymmetricModesTest {
|
||||
// ---------------------------
|
||||
// Helper Methods
|
||||
// ---------------------------
|
||||
|
||||
/**
|
||||
* Generates a secure 256-bit AES key.
|
||||
*
|
||||
|
||||
@@ -14,35 +14,36 @@ import java.nio.file.Files;
|
||||
import java.io.IOException;
|
||||
|
||||
public class UniversalFlowTest {
|
||||
|
||||
public void simpleAESEncryption() throws Exception {
|
||||
String algorithm = "AES";
|
||||
String otherAlgorithm = loadAlgorithmFromDisk();
|
||||
String algorithm = "AES";
|
||||
String otherAlgorithm = loadAlgorithmFromDisk();
|
||||
|
||||
// Randomly select between the known algorithm and the one loaded from disk
|
||||
String selectedAlgorithm = (new Random().nextInt(2) == 0) ? algorithm : otherAlgorithm;
|
||||
// Randomly select between the known algorithm and the one loaded from disk
|
||||
String selectedAlgorithm = (new Random().nextInt(2) == 0) ? algorithm : otherAlgorithm;
|
||||
|
||||
KeyGenerator keyGen = KeyGenerator.getInstance(selectedAlgorithm);
|
||||
keyGen.init(256); // 256-bit AES key.
|
||||
SecretKey key = keyGen.generateKey();
|
||||
String algorithm2 = "AES/GCM/NoPadding";
|
||||
Cipher cipher = Cipher.getInstance(algorithm2);
|
||||
byte[] iv = new byte[12]; // 12-byte IV recommended for GCM.
|
||||
new SecureRandom().nextBytes(iv);
|
||||
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv); // 128-bit authentication tag.
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, gcmSpec);
|
||||
byte[] encryptedData = cipher.doFinal("Sensitive Data".getBytes());
|
||||
}
|
||||
KeyGenerator keyGen = KeyGenerator.getInstance(selectedAlgorithm);
|
||||
keyGen.init(256); // 256-bit AES key.
|
||||
SecretKey key = keyGen.generateKey();
|
||||
String algorithm2 = "AES/GCM/NoPadding";
|
||||
Cipher cipher = Cipher.getInstance(algorithm2);
|
||||
byte[] iv = new byte[12]; // 12-byte IV recommended for GCM.
|
||||
new SecureRandom().nextBytes(iv);
|
||||
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv); // 128-bit authentication tag.
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, gcmSpec);
|
||||
byte[] encryptedData = cipher.doFinal("Sensitive Data".getBytes());
|
||||
}
|
||||
|
||||
// Method to load algorithm from disk
|
||||
private String loadAlgorithmFromDisk() {
|
||||
try {
|
||||
// Implementation to load algorithm name from a file
|
||||
Path path = Paths.get("algorithm.txt");
|
||||
return Files.readString(path).trim();
|
||||
} catch (IOException e) {
|
||||
// Fallback to default algorithm if loading fails
|
||||
System.err.println("Failed to load algorithm from disk: " + e.getMessage());
|
||||
return "AES";
|
||||
private String loadAlgorithmFromDisk() {
|
||||
try {
|
||||
// Implementation to load algorithm name from a file
|
||||
Path path = Paths.get("algorithm.txt");
|
||||
return Files.readString(path).trim();
|
||||
} catch (IOException e) {
|
||||
// Fallback to default algorithm if loading fails
|
||||
System.err.println("Failed to load algorithm from disk: " + e.getMessage());
|
||||
return "AES";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user