22
33// import org.bouncycastle.jce.provider.BouncyCastleProvider;
44// import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
5-
5+ import java .security .*;
6+ import java .security .spec .ECGenParameterSpec ;
7+ import java .util .Arrays ;
8+ import java .util .Base64 ;
69import javax .crypto .Cipher ;
710import javax .crypto .KeyAgreement ;
811import javax .crypto .KeyGenerator ;
912import javax .crypto .Mac ;
1013import javax .crypto .SecretKey ;
1114import javax .crypto .spec .GCMParameterSpec ;
1215import javax .crypto .spec .SecretKeySpec ;
13- import java .security .*;
14- import java .security .spec .ECGenParameterSpec ;
15- import java .util .Arrays ;
16- import java .util .Base64 ;
1716
1817/**
19- * AsymmetricEncryptionMacHybridCryptosystem demonstrates hybrid
20- * cryptosystems that combine asymmetric encryption with a MAC.
18+ * AsymmetricEncryptionMacHybridCryptosystem demonstrates hybrid cryptosystems
19+ * that combine asymmetric encryption with a MAC.
2120 *
22- * Flows:
23- * 1. RSA-OAEP + HMAC:
24- * - Secure Flow: Uses 2048-bit RSA-OAEP (with SHA256andMGF1Padding) to
25- * encapsulate a freshly generated AES key;
26- * then encrypts using AES-GCM with a random nonce and computes HMAC-SHA256 over
27- * the ciphertext.
28- * - Insecure Flow: Uses 1024-bit RSA (RSA/ECB/PKCS1Padding), AES-GCM with a
29- * fixed IV, and HMAC-SHA1.
21+ * Flows: 1. RSA-OAEP + HMAC: - Secure Flow: Uses 2048-bit RSA-OAEP (with
22+ * SHA256andMGF1Padding) to encapsulate a freshly generated AES key; then
23+ * encrypts using AES-GCM with a random nonce and computes HMAC-SHA256 over the
24+ * ciphertext. - Insecure Flow: Uses 1024-bit RSA (RSA/ECB/PKCS1Padding),
25+ * AES-GCM with a fixed IV, and HMAC-SHA1.
3026 *
31- * 2. ECIES + HMAC:
32- * - Secure Flow: Uses ephemeral ECDH key pairs (secp256r1); derives a shared
33- * secret and applies a simple KDF (SHA-256)
34- * to derive a 128-bit AES key; then uses AES-GCM with a random nonce and
35- * computes HMAC-SHA256.
36- * - Insecure Flow: Reuses a static EC key pair, directly truncates the shared
37- * secret without a proper KDF,
38- * uses a fixed IV, and computes HMAC-SHA1.
27+ * 2. ECIES + HMAC: - Secure Flow: Uses ephemeral ECDH key pairs (secp256r1);
28+ * derives a shared secret and applies a simple KDF (SHA-256) to derive a
29+ * 128-bit AES key; then uses AES-GCM with a random nonce and computes
30+ * HMAC-SHA256. - Insecure Flow: Reuses a static EC key pair, directly truncates
31+ * the shared secret without a proper KDF, uses a fixed IV, and computes
32+ * HMAC-SHA1.
3933 *
40- * 3. Dynamic Hybrid Selection:
41- * - Chooses between flows based on a configuration string.
34+ * 3. Dynamic Hybrid Selection: - Chooses between flows based on a configuration
35+ * string.
4236 *
43- * SAST/CBOM Notes:
44- * - Secure flows use proper ephemeral key generation, secure key sizes, KDF
45- * usage, and random nonces/IVs.
46- * - Insecure flows (static key reuse, fixed nonces, weak key sizes, raw shared
47- * secret truncation, and deprecated algorithms)
48- * should be flagged.
37+ * SAST/CBOM Notes: - Secure flows use proper ephemeral key generation, secure
38+ * key sizes, KDF usage, and random nonces/IVs. - Insecure flows (static key
39+ * reuse, fixed nonces, weak key sizes, raw shared secret truncation, and
40+ * deprecated algorithms) should be flagged.
4941 */
5042public class AsymmetricEncryptionMacHybridCryptosystem {
5143
5244 // static {
5345 // Security.addProvider(new BouncyCastleProvider());
5446 // Security.addProvider(new BouncyCastlePQCProvider());
5547 // }
56-
5748 // ---------- Result Class ----------
5849 public static class HybridResult {
50+
5951 private final byte [] encapsulatedKey ;
6052 private final byte [] ciphertext ;
6153 private final byte [] mac ;
@@ -79,14 +71,13 @@ public byte[] getMac() {
7971 }
8072
8173 public String toBase64String () {
82- return "EncapsulatedKey: " + Base64 .getEncoder ().encodeToString (encapsulatedKey ) +
83- "\n Ciphertext: " + Base64 .getEncoder ().encodeToString (ciphertext ) +
84- "\n MAC: " + Base64 .getEncoder ().encodeToString (mac );
74+ return "EncapsulatedKey: " + Base64 .getEncoder ().encodeToString (encapsulatedKey )
75+ + "\n Ciphertext: " + Base64 .getEncoder ().encodeToString (ciphertext )
76+ + "\n MAC: " + Base64 .getEncoder ().encodeToString (mac );
8577 }
8678 }
8779
8880 // ---------- Helper Methods ----------
89-
9081 /**
9182 * Generates an ephemeral ECDH key pair on secp256r1.
9283 */
@@ -107,10 +98,10 @@ public KeyPair generateX25519KeyPair() throws Exception {
10798
10899 /**
109100 * Derives a shared secret using the provided key agreement algorithm.
110- *
101+ *
111102 * @param privateKey The private key.
112- * @param publicKey The corresponding public key.
113- * @param algorithm The key agreement algorithm (e.g., "ECDH" or "X25519").
103+ * @param publicKey The corresponding public key.
104+ * @param algorithm The key agreement algorithm (e.g., "ECDH" or "X25519").
114105 * @return The shared secret.
115106 */
116107 public byte [] deriveSharedSecret (PrivateKey privateKey , PublicKey publicKey , String algorithm ) throws Exception {
@@ -123,8 +114,8 @@ public byte[] deriveSharedSecret(PrivateKey privateKey, PublicKey publicKey, Str
123114 /**
124115 * A simple KDF that hashes the input with SHA-256 and returns the first
125116 * numBytes.
126- *
127- * @param input The input byte array.
117+ *
118+ * @param input The input byte array.
128119 * @param numBytes The desired number of output bytes.
129120 * @return The derived key material.
130121 */
@@ -147,7 +138,6 @@ public byte[] concatenate(byte[] a, byte[] b) {
147138 // =====================================================
148139 // 1. RSA-OAEP + HMAC Hybrid Cryptosystem
149140 // =====================================================
150-
151141 /**
152142 * Generates a secure 2048-bit RSA key pair.
153143 */
@@ -216,7 +206,6 @@ public HybridResult insecureRSAHybridEncryption(byte[] plaintext) throws Excepti
216206 // =====================================================
217207 // 2. ECIES + HMAC Hybrid Cryptosystem
218208 // =====================================================
219-
220209 /**
221210 * Secure hybrid encryption using ECIES (via ECDH) + HMAC-SHA256.
222211 */
@@ -268,16 +257,15 @@ public HybridResult insecureECIESHybridEncryption(byte[] plaintext) throws Excep
268257 // =====================================================
269258 // 3. Dynamic Hybrid Selection
270259 // =====================================================
271-
272260 /**
273261 * Dynamically selects a hybrid encryption flow based on configuration.
274262 * SAST: Dynamic selection introduces risk if insecure defaults are chosen.
275263 *
276- * @param config The configuration string ("secureRSA", "insecureRSA",
277- * "secureECIES", "insecureECIES").
264+ * @param config The configuration string ("secureRSA", "insecureRSA",
265+ * "secureECIES", "insecureECIES").
278266 * @param plaintext The plaintext to encrypt.
279267 * @return A Base64-encoded string representation of the hybrid encryption
280- * result.
268+ * result.
281269 * @throws Exception if an error occurs.
282270 */
283271 public String dynamicHybridEncryption (String config , byte [] plaintext ) throws Exception {
@@ -300,10 +288,8 @@ public String dynamicHybridEncryption(String config, byte[] plaintext) throws Ex
300288 // =====================================================
301289 // 4. Helper Methods for HMAC and Symmetric Encryption
302290 // =====================================================
303-
304291 /**
305- * Secure HMAC using HMAC-SHA256.
306- * SAST: HMAC-SHA256 is secure.
292+ * Secure HMAC using HMAC-SHA256. SAST: HMAC-SHA256 is secure.
307293 */
308294 public byte [] secureHMACSHA256 (String message , byte [] key ) throws Exception {
309295 Mac mac = Mac .getInstance ("HmacSHA256" , "BC" );
@@ -313,8 +299,8 @@ public byte[] secureHMACSHA256(String message, byte[] key) throws Exception {
313299 }
314300
315301 /**
316- * Insecure HMAC using HMAC-SHA1.
317- * SAST: HMAC-SHA1 is deprecated and insecure.
302+ * Insecure HMAC using HMAC-SHA1. SAST: HMAC-SHA1 is deprecated and
303+ * insecure.
318304 */
319305 public byte [] insecureHMACSHA1 (String message , byte [] key ) throws Exception {
320306 Mac mac = Mac .getInstance ("HmacSHA1" , "BC" );
@@ -326,10 +312,9 @@ public byte[] insecureHMACSHA1(String message, byte[] key) throws Exception {
326312 // =====================================================
327313 // 5. Helper Methods for Key/Nonce Generation
328314 // =====================================================
329-
330315 /**
331- * Generates a secure 256-bit AES key.
332- * SAST: Uses SecureRandom for key generation.
316+ * Generates a secure 256-bit AES key. SAST: Uses SecureRandom for key
317+ * generation.
333318 */
334319 public SecretKey generateAESKey () throws Exception {
335320 KeyGenerator kg = KeyGenerator .getInstance ("AES" );
0 commit comments