2828import com .adyen .model .terminal .security .SecurityTrailer ;
2929import com .adyen .terminal .security .exception .NexoCryptoException ;
3030import org .apache .commons .codec .binary .Base64 ;
31+
3132import javax .crypto .BadPaddingException ;
3233import javax .crypto .Cipher ;
3334import javax .crypto .IllegalBlockSizeException ;
4142import java .security .InvalidKeyException ;
4243import java .security .MessageDigest ;
4344import java .security .NoSuchAlgorithmException ;
44- import java .security .Provider ;
4545import java .security .SecureRandom ;
4646
4747import static com .adyen .model .terminal .security .NexoDerivedKey .NEXO_IV_LENGTH ;
4848
4949public class NexoCrypto {
5050
51- private static SecureRandom secureRandom = new SecureRandom ();
52- private static final Provider PROVIDER = secureRandom .getProvider ();
5351 private final SecurityKey securityKey ;
5452 private volatile NexoDerivedKey nexoDerivedKey ;
5553
@@ -58,7 +56,7 @@ public NexoCrypto(SecurityKey securityKey) throws NexoCryptoException {
5856 this .securityKey = securityKey ;
5957 }
6058
61- public SaleToPOISecuredMessage encrypt (String saleToPoiMessageJson , MessageHeader messageHeader ) throws Exception {
59+ public SaleToPOISecuredMessage encrypt (String saleToPoiMessageJson , MessageHeader messageHeader ) throws GeneralSecurityException {
6260 NexoDerivedKey derivedKey = getNexoDerivedKey ();
6361 byte [] saleToPoiMessageByteArray = saleToPoiMessageJson .getBytes (StandardCharsets .UTF_8 );
6462 byte [] ivNonce = generateRandomIvNonce ();
@@ -80,7 +78,7 @@ public SaleToPOISecuredMessage encrypt(String saleToPoiMessageJson, MessageHeade
8078 return saleToPoiSecuredMessage ;
8179 }
8280
83- public String decrypt (SaleToPOISecuredMessage saleToPoiSecuredMessage ) throws Exception {
81+ public String decrypt (SaleToPOISecuredMessage saleToPoiSecuredMessage ) throws GeneralSecurityException , NexoCryptoException {
8482 NexoDerivedKey derivedKey = getNexoDerivedKey ();
8583 byte [] encryptedSaleToPoiMessageByteArray = Base64 .decodeBase64 (saleToPoiSecuredMessage .getNexoBlob ().getBytes ());
8684 byte [] ivNonce = saleToPoiSecuredMessage .getSecurityTrailer ().getNonce ();
@@ -114,19 +112,13 @@ private NexoDerivedKey getNexoDerivedKey() throws GeneralSecurityException {
114112 return nexoDerivedKey ;
115113 }
116114
117- /**
118- * Encrypt or decrypt data given a iv modifier and using the specified key
119- * <p>
120- * The actual iv is computed by taking the iv from the key material and xoring it with ivmod
121- */
122115 private byte [] crypt (byte [] bytes , NexoDerivedKey dk , byte [] ivNonce , int mode )
123116 throws NoSuchAlgorithmException , NoSuchPaddingException ,
124117 IllegalBlockSizeException , BadPaddingException , InvalidKeyException , InvalidAlgorithmParameterException {
125118
126119 Cipher cipher = Cipher .getInstance ("AES/CBC/PKCS5Padding" );
127120 SecretKeySpec secretKeySpec = new SecretKeySpec (dk .getCipherKey (), "AES" );
128121
129- // xor dk.iv and the iv modifier
130122 byte [] iv = dk .getIv ();
131123 byte [] actualIV = new byte [NEXO_IV_LENGTH ];
132124 for (int i = 0 ; i < NEXO_IV_LENGTH ; i ++) {
@@ -138,9 +130,6 @@ private byte[] crypt(byte[] bytes, NexoDerivedKey dk, byte[] ivNonce, int mode)
138130 return cipher .doFinal (bytes );
139131 }
140132
141- /**
142- * Compute a hmac using the hmacKey
143- */
144133 private byte [] hmac (byte [] bytes , NexoDerivedKey derivedKey ) throws NoSuchAlgorithmException , InvalidKeyException {
145134 Mac mac = Mac .getInstance ("HmacSHA256" );
146135 SecretKeySpec s = new SecretKeySpec (derivedKey .getHmacKey (), "HmacSHA256" );
@@ -149,26 +138,21 @@ private byte[] hmac(byte[] bytes, NexoDerivedKey derivedKey) throws NoSuchAlgori
149138 return mac .doFinal (bytes );
150139 }
151140
152- /**
153- * Validate the hmac from a received message
154- */
155141 private void validateHmac (byte [] receivedHmac , byte [] decryptedMessage , NexoDerivedKey derivedKey ) throws NexoCryptoException , InvalidKeyException , NoSuchAlgorithmException {
156142 byte [] hmac = hmac (decryptedMessage , derivedKey );
157143 boolean valid = MessageDigest .isEqual (hmac , receivedHmac );
158144
159145 if (!valid ) {
160- throw new NexoCryptoException ("Hmac validation failed" );
146+ throw new NexoCryptoException ("HMAC validation failed" );
161147 }
162148 }
163149
164- /**
165- * Generate a random iv nonce with cryptographically strongest non blocking RNG
166- */
167150 private byte [] generateRandomIvNonce () {
168151 byte [] ivNonce = new byte [NEXO_IV_LENGTH ];
152+ SecureRandom secureRandom ;
169153 try {
170- secureRandom = SecureRandom .getInstance ("NativePRNGNonBlocking" , PROVIDER );
171- } catch (Exception NoSuchAlgorithmException ) {
154+ secureRandom = SecureRandom .getInstance ("NativePRNGNonBlocking" );
155+ } catch (NoSuchAlgorithmException e ) {
172156 secureRandom = new SecureRandom ();
173157 }
174158 secureRandom .nextBytes (ivNonce );
0 commit comments