mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
314 lines
13 KiB
Java
314 lines
13 KiB
Java
package com.example.crypto.algorithms;
|
|
|
|
// import org.bouncycastle.crypto.digests.SHA3Digest;
|
|
// import org.bouncycastle.crypto.digests.Blake2bDigest;
|
|
// import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.security.*;
|
|
import java.util.Base64;
|
|
import java.util.Properties;
|
|
import javax.crypto.Mac;
|
|
import javax.crypto.SecretKey;
|
|
import javax.crypto.SecretKeyFactory;
|
|
import javax.crypto.spec.SecretKeySpec;
|
|
import javax.crypto.spec.PBEKeySpec;
|
|
|
|
/**
|
|
* This class demonstrates various hashing, HMAC, and password hashing
|
|
* techniques.
|
|
*
|
|
* SAST/CBOM Classification Notes:
|
|
*
|
|
* 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.
|
|
*
|
|
* 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.
|
|
*
|
|
* 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.
|
|
* - 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.
|
|
*
|
|
* 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.
|
|
*
|
|
* 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.
|
|
*/
|
|
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.
|
|
*/
|
|
public void simpleSHA256Hash() throws Exception {
|
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
|
byte[] hash = digest.digest("Simple Test Data".getBytes());
|
|
System.out.println("SHA-256 Hash: " + Base64.getEncoder().encodeToString(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
|
|
* vulnerabilities.
|
|
*/
|
|
public void insecureMD5Hash() throws Exception {
|
|
MessageDigest md5Digest = MessageDigest.getInstance("MD5");
|
|
byte[] hash = md5Digest.digest("Weak Hash Example".getBytes());
|
|
System.out.println("MD5 Hash (Insecure): " + Base64.getEncoder().encodeToString(hash));
|
|
}
|
|
|
|
// /**
|
|
// * Computes a SHA3-256 hash using BouncyCastle's SHA3Digest.
|
|
// *
|
|
// * CBOM/SAST Classification:
|
|
// * - Uses SHA3-256: Classified as secure.
|
|
// * - SAST: BouncyCastle's implementation is considered reliable.
|
|
// */
|
|
// public void hashWithBouncyCastleSHA3(String input) {
|
|
// SHA3Digest digest = new SHA3Digest(256);
|
|
// byte[] inputBytes = input.getBytes();
|
|
// digest.update(inputBytes, 0, inputBytes.length);
|
|
// byte[] hash = new byte[digest.getDigestSize()];
|
|
// digest.doFinal(hash, 0);
|
|
// System.out.println("SHA3-256 (BC) Hash: " + Base64.getEncoder().encodeToString(hash));
|
|
// }
|
|
// /**
|
|
// * Computes a BLAKE2b-512 hash using BouncyCastle's Blake2bDigest.
|
|
// *
|
|
// * CBOM/SAST Classification:
|
|
// * - Uses BLAKE2b-512: Classified as secure.
|
|
// * - SAST: BLAKE2b is modern and fast, considered secure when used correctly.
|
|
// */
|
|
// public void hashWithBouncyCastleBlake2b(String input) {
|
|
// Blake2bDigest digest = new Blake2bDigest(512);
|
|
// byte[] inputBytes = input.getBytes();
|
|
// digest.update(inputBytes, 0, inputBytes.length);
|
|
// byte[] hash = new byte[digest.getDigestSize()];
|
|
// 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.
|
|
*
|
|
* @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 {
|
|
Signature signature = Signature.getInstance("SHA256withRSA");
|
|
signature.initSign(privateKey);
|
|
signature.update(input.getBytes());
|
|
byte[] signedData = signature.sign();
|
|
System.out.println("Signed Hash: " + Base64.getEncoder().encodeToString(signedData));
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*
|
|
* @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.
|
|
* @return true if the signature is valid, false otherwise.
|
|
*/
|
|
public boolean verifyHashSignature(String input, byte[] signedHash, PublicKey publicKey) throws Exception {
|
|
Signature signature = Signature.getInstance("SHA256withRSA");
|
|
signature.initVerify(publicKey);
|
|
signature.update(input.getBytes());
|
|
return signature.verify(signedHash);
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*
|
|
* @param data The input data.
|
|
* @param expectedHash The expected Base64-encoded hash.
|
|
*/
|
|
public void hashForDataIntegrityCheck(String data, String expectedHash) throws Exception {
|
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
|
byte[] hash = digest.digest(data.getBytes());
|
|
String computedHash = Base64.getEncoder().encodeToString(hash);
|
|
System.out.println("Computed Hash: " + computedHash);
|
|
System.out.println("Validation: " + (computedHash.equals(expectedHash) ? "Pass" : "Fail"));
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*
|
|
* @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"};
|
|
for (String algorithm : algorithms) {
|
|
MessageDigest digest = MessageDigest.getInstance(algorithm);
|
|
byte[] hash = digest.digest(input.getBytes());
|
|
System.out.println(algorithm + " Hash: " + Base64.getEncoder().encodeToString(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.
|
|
*
|
|
* @param input The input data.
|
|
* @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"};
|
|
for (String algorithm : algorithms) {
|
|
Mac mac = Mac.getInstance(algorithm);
|
|
SecretKey secretKey = new SecretKeySpec(key, algorithm);
|
|
mac.init(secretKey);
|
|
byte[] hmac = mac.doFinal(input.getBytes());
|
|
System.out.println(algorithm + " HMAC: " + Base64.getEncoder().encodeToString(hmac));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*
|
|
* @param password The password to hash.
|
|
*/
|
|
public void hashForPasswordStorage(String password) throws Exception {
|
|
byte[] salt = generateSecureSalt(16);
|
|
// 10,000 iterations and a 256-bit derived key.
|
|
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10000, 256);
|
|
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
|
byte[] hash = factory.generateSecret(spec).getEncoded();
|
|
System.out.println("PBKDF2 Hash: " + Base64.getEncoder().encodeToString(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.
|
|
*/
|
|
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));
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
public void insecureHashBasedRNG() throws Exception {
|
|
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));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*
|
|
* @param configPath Path to the configuration file.
|
|
* @return The hash algorithm to be used (default is SHA-256).
|
|
*/
|
|
private String loadHashAlgorithmFromConfig(String configPath) {
|
|
Properties properties = new Properties();
|
|
try (FileInputStream fis = new FileInputStream(configPath)) {
|
|
properties.load(fis);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
return properties.getProperty("hash.algorithm", "SHA-256");
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* hashing.
|
|
*
|
|
* @param length The desired salt length.
|
|
* @return A byte array representing the salt.
|
|
*/
|
|
private byte[] generateSecureSalt(int length) {
|
|
byte[] salt = new byte[length];
|
|
new SecureRandom().nextBytes(salt);
|
|
return salt;
|
|
}
|
|
}
|