Skip to content

Commit 5242529

Browse files
committed
Use a dynamically-generated, random IV
1 parent ace4cc1 commit 5242529

File tree

1 file changed

+7
-23
lines changed

1 file changed

+7
-23
lines changed

src/main/java/com/adyen/terminal/security/NexoCrypto.java

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.adyen.model.terminal.security.SecurityTrailer;
2929
import com.adyen.terminal.security.exception.NexoCryptoException;
3030
import org.apache.commons.codec.binary.Base64;
31+
3132
import javax.crypto.BadPaddingException;
3233
import javax.crypto.Cipher;
3334
import javax.crypto.IllegalBlockSizeException;
@@ -41,15 +42,12 @@
4142
import java.security.InvalidKeyException;
4243
import java.security.MessageDigest;
4344
import java.security.NoSuchAlgorithmException;
44-
import java.security.Provider;
4545
import java.security.SecureRandom;
4646

4747
import static com.adyen.model.terminal.security.NexoDerivedKey.NEXO_IV_LENGTH;
4848

4949
public 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

Comments
 (0)