11package com .mastercard .developer .encryption .aes ;
22
33import com .mastercard .developer .encryption .EncryptionException ;
4- import com .mastercard .developer .encryption .jwe .JweHeader ;
54import com .mastercard .developer .encryption .jwe .JweObject ;
65import com .mastercard .developer .json .JsonEngine ;
76import com .mastercard .developer .utils .EncodingUtils ;
1211import javax .crypto .spec .SecretKeySpec ;
1312import java .nio .charset .StandardCharsets ;
1413
15- import static org .junit .Assert .*;
14+ import static org .junit .Assert .assertEquals ;
15+ import static org .junit .Assert .assertNotNull ;
1616
1717public class AESCBCTest {
1818
@@ -21,19 +21,55 @@ public class AESCBCTest {
2121
2222 @ Test
2323 public void testDecrypt_ShouldDecryptSuccessfully_WhenHmacVerificationIsEnabledAndTagIsValid () throws Exception {
24- // Given: A properly encrypted JWE object with valid HMAC tag
25- // This is a real A128CBC-HS256 encrypted payload
26- String jweString = "eyJraWQiOiI3NjFiMDAzYzFlYWRlM2E1NDkwZTUwMDBkMzc4ODdiYWE1ZTZlYzBlMjI2YzA3NzA2ZTU5OTQ1MWZjMDMyYTc5IiwiY3R5IjoiYXBwbGljYXRpb25cL2pzb24iLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.5bsamlChk0HR3Nqg2UPJ2Fw4Y0MvC2pwWzNv84jYGkOXyqp1iwQSgETGaplIa7JyLg1ZWOqwNHEx3N7gsN4nzwAnVgz0eta6SsoQUE9YQ-5jek0COslUkoqIQjlQYJnYur7pqttDibj87fcw13G2agle5fL99j1QgFPjNPYqH88DMv481XGFa8O3VfJhW93m73KD2gvE5GasOPOkFK9wjKXc9lMGSgSArp3Awbc_oS2Cho_SbsvuEQwkhnQc2JKT3IaSWu8yK7edNGwD6OZJLhMJzWJlY30dUt2Eqe1r6kMT0IDRl7jHJnVIr2Qpe56CyeZ9V0aC5RH1mI5dYk4kHg.yI0CS3NdBrz9CCW2jwBSDw.6zr2pOSmAGdlJG0gbH53Eg.UFgf3-P9UjgMocEu7QA_vQ" ;
24+ // Given: A properly constructed JWE with correct HMAC tag
25+ byte [] cekBytes = new byte [32 ]; // 256-bit key (128-bit HMAC key + 128-bit AES key)
26+ java .security .SecureRandom random = new java .security .SecureRandom ();
27+ random .nextBytes (cekBytes );
28+
29+ SecretKeySpec cek = new SecretKeySpec (cekBytes , "AES" );
30+ SecretKeySpec hmacKey = new SecretKeySpec (cekBytes , 0 , 16 , "HmacSHA256" );
31+ SecretKeySpec aesKey = new SecretKeySpec (cekBytes , 16 , 16 , "AES" );
32+
33+ // Encrypt data
34+ byte [] plainText = "Valid HMAC Test Data" .getBytes (StandardCharsets .UTF_8 );
35+ byte [] iv = new byte [16 ];
36+ random .nextBytes (iv );
37+
38+ javax .crypto .Cipher cipher = javax .crypto .Cipher .getInstance ("AES/CBC/PKCS5Padding" );
39+ cipher .init (javax .crypto .Cipher .ENCRYPT_MODE , aesKey , new javax .crypto .spec .IvParameterSpec (iv ));
40+ byte [] cipherText = cipher .doFinal (plainText );
41+
42+ // Compute proper HMAC according to JWE spec
43+ String rawHeader = EncodingUtils .base64UrlEncode ("{\" enc\" :\" A128CBC-HS256\" ,\" alg\" :\" RSA-OAEP-256\" }" .getBytes ());
44+ byte [] aad = rawHeader .getBytes (StandardCharsets .US_ASCII );
45+
46+ javax .crypto .Mac mac = javax .crypto .Mac .getInstance ("HmacSHA256" );
47+ mac .init (hmacKey );
48+ mac .update (aad );
49+ mac .update (iv );
50+ mac .update (cipherText );
51+
52+ // Add AL (AAD length in bits as 64-bit big-endian)
53+ long aadLengthBits = (long ) aad .length * 8 ;
54+ java .nio .ByteBuffer alBuffer = java .nio .ByteBuffer .allocate (8 );
55+ alBuffer .putLong (aadLengthBits );
56+ mac .update (alBuffer .array ());
57+
58+ byte [] hmacOutput = mac .doFinal ();
59+ byte [] authTag = new byte [16 ]; // First 16 bytes (tag length = key length for A128CBC-HS256)
60+ System .arraycopy (hmacOutput , 0 , authTag , 0 , 16 );
61+
62+ // Construct JWE string
63+ String jweString = rawHeader + ".dummy." + EncodingUtils .base64UrlEncode (iv ) + "." +
64+ EncodingUtils .base64UrlEncode (cipherText ) + "." + EncodingUtils .base64UrlEncode (authTag );
2765 JweObject jweObject = JweObject .parse (jweString , JsonEngine .getDefault ());
2866
29- // When: Decrypt with a known CEK and HMAC verification enabled
30- // Note: This is a test key matching the encrypted payload
31- byte [] cekBytes = new byte [32 ]; // 256-bit key (128-bit HMAC key + 128-bit AES key)
32- // For testing, we'll use the actual encrypted key from the JWE
33- // In a real scenario, this would be unwrapped from the encrypted key
67+ // When: Decrypt with HMAC verification enabled
68+ byte [] result = AESCBC .decrypt (cek , jweObject , true );
3469
35- // We can't directly test without the unwrapped key, so let's test the verification logic
36- // by creating a mock scenario
70+ // Then: Should succeed and return correct plaintext
71+ assertNotNull (result );
72+ assertEquals ("Valid HMAC Test Data" , new String (result , StandardCharsets .UTF_8 ));
3773 }
3874
3975 @ Test
0 commit comments