Skip to content

Commit f96fbb3

Browse files
Merge pull request #86 from Mastercard/supporting-iv-size-12
Adding support for IV size 12
2 parents dafbd3e + 9c0257e commit f96fbb3

File tree

13 files changed

+179
-11
lines changed

13 files changed

+179
-11
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ JweConfig config = JweConfigBuilder.aJweEncryptionConfig()
170170
.withEncryptionPath("$.path.to.foo", "$.path.to.encryptedFoo")
171171
.withDecryptionPath("$.path.to.encryptedFoo.encryptedValue", "$.path.to.foo")
172172
.withEncryptedValueFieldName("encryptedValue")
173+
.withIVSize(16) // available values are 12 or 16. If not specified, default value is 16.
173174
.build();
174175
```
175176

pom.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.mastercard.developer</groupId>
88
<artifactId>client-encryption</artifactId>
9-
<version>1.7.13-SNAPSHOT</version>
9+
<version>1.8.0</version>
1010
<packaging>jar</packaging>
1111
<description>Library for Mastercard API compliant payload encryption/decryption</description>
1212
<url>https://github.com/Mastercard/client-encryption-java</url>
@@ -96,7 +96,6 @@
9696
<version>4.13.1</version>
9797
<scope>test</scope>
9898
</dependency>
99-
10099
<dependency>
101100
<groupId>org.junit.jupiter</groupId>
102101
<artifactId>junit-jupiter-params</artifactId>

src/main/java/com/mastercard/developer/encryption/EncryptionConfig.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ public enum Scheme {
4646
*/
4747
PrivateKey decryptionKey;
4848

49+
50+
/**
51+
* IV size in bytes
52+
*/
53+
54+
Integer ivSize = 16;
55+
4956
/**
5057
* A list of JSON paths to encrypt in request payloads.
5158
* Example:
@@ -107,4 +114,6 @@ Map<String, String> getDecryptionPaths() {
107114
String getEncryptedValueFieldName() {
108115
return encryptedValueFieldName;
109116
}
117+
118+
public Integer getIVSize() { return ivSize; }
110119
}

src/main/java/com/mastercard/developer/encryption/EncryptionConfigBuilder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ abstract class EncryptionConfigBuilder {
2323
protected Map<String, String> decryptionPaths = new HashMap<>();
2424
protected String encryptedValueFieldName;
2525

26+
protected Integer ivSize = 16;
27+
2628
void computeEncryptionKeyFingerprintWhenNeeded() throws EncryptionException {
2729
try {
2830
if ((encryptionCertificate == null && encryptionKey == null) || !isNullOrEmpty(encryptionKeyFingerprint)) {

src/main/java/com/mastercard/developer/encryption/FieldLevelEncryptionConfigBuilder.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,16 @@ public FieldLevelEncryptionConfigBuilder withEncryptionKeyFingerprintHeaderName(
186186
return this;
187187
}
188188

189+
/**
190+
* See: {@link EncryptionConfig#ivSize}.
191+
*/
192+
public FieldLevelEncryptionConfigBuilder withEncryptionIVSize(Integer ivSize) {
193+
if (ivSize == 12 || ivSize == 16) {
194+
this.ivSize = ivSize;
195+
return this;
196+
}
197+
throw new IllegalArgumentException("Supported IV Sizes are either 12 or 16!");
198+
}
189199
/**
190200
* Build a {@link com.mastercard.developer.encryption.FieldLevelEncryptionConfig}.
191201
* @throws EncryptionException
@@ -209,6 +219,7 @@ public FieldLevelEncryptionConfig build() throws EncryptionException {
209219
config.encryptionCertificate = this.encryptionCertificate;
210220
config.oaepPaddingDigestAlgorithm = this.oaepPaddingDigestAlgorithm;
211221
config.ivFieldName = this.ivFieldName;
222+
config.ivSize = this.ivSize;
212223
config.oaepPaddingDigestAlgorithmFieldName = this.oaepPaddingDigestAlgorithmFieldName;
213224
config.decryptionPaths = this.decryptionPaths;
214225
config.encryptedKeyFieldName = this.encryptedKeyFieldName;

src/main/java/com/mastercard/developer/encryption/FieldLevelEncryptionParams.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public FieldLevelEncryptionParams(String ivValue, String encryptedKeyValue, Stri
4343
public static FieldLevelEncryptionParams generate(FieldLevelEncryptionConfig config) throws EncryptionException {
4444

4545
// Generate a random IV
46-
IvParameterSpec ivParameterSpec = AESEncryption.generateIv();
46+
IvParameterSpec ivParameterSpec = AESEncryption.generateIv(config.getIVSize());
4747
String ivSpecValue = encodeBytes(ivParameterSpec.getIV(), config.fieldValueEncoding);
4848

4949
// Generate an AES secret key

src/main/java/com/mastercard/developer/encryption/JweConfigBuilder.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public JweConfig build() throws EncryptionException {
3333
config.decryptionPaths = this.decryptionPaths.isEmpty() ? Collections.singletonMap("$.encryptedData", "$") : this.decryptionPaths;
3434
config.encryptedValueFieldName = this.encryptedValueFieldName == null ? "encryptedData" : this.encryptedValueFieldName;
3535
config.scheme = EncryptionConfig.Scheme.JWE;
36+
config.ivSize = ivSize;
3637
return config;
3738
}
3839

@@ -82,9 +83,8 @@ public JweConfigBuilder withDecryptionPath(String jsonPathIn, String jsonPathOut
8283
return this;
8384
}
8485

85-
/**
86-
* See: {@link EncryptionConfig#encryptedValueFieldName}.
87-
*/
86+
87+
8888
public JweConfigBuilder withEncryptedValueFieldName(String encryptedValueFieldName) {
8989
this.encryptedValueFieldName = encryptedValueFieldName;
9090
return this;
@@ -95,9 +95,21 @@ public JweConfigBuilder withEncryptionKeyFingerprint(String encryptionKeyFingerp
9595
return this;
9696
}
9797

98+
/**
99+
* See: {@link EncryptionConfig#ivSize}.
100+
*/
101+
public JweConfigBuilder withEncryptionIVSize(Integer ivSize) {
102+
if (ivSize == 12 || ivSize == 16) {
103+
this.ivSize = ivSize;
104+
return this;
105+
}
106+
throw new IllegalArgumentException("Supported IV Sizes are either 12 or 16!");
107+
}
108+
98109
private void checkParameterValues() {
99110
if (decryptionKey == null && encryptionCertificate == null && encryptionKey == null) {
100111
throw new IllegalArgumentException("You must include at least an encryption key/certificate or a decryption key");
101112
}
102113
}
114+
103115
}

src/main/java/com/mastercard/developer/encryption/aes/AESEncryption.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ private AESEncryption() {
1414
// Nothing to do here
1515
}
1616

17-
public static IvParameterSpec generateIv() throws EncryptionException {
17+
public static IvParameterSpec generateIv(Integer ivSize) throws EncryptionException {
1818
try {
1919
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
20-
byte[] ivBytes = new byte[16];
20+
byte[] ivBytes = new byte[ivSize];
2121
secureRandom.nextBytes(ivBytes);
2222
return new IvParameterSpec(ivBytes);
2323
} catch (GeneralSecurityException e) {

src/main/java/com/mastercard/developer/encryption/jwe/JweObject.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public static String encrypt(JweConfig config, String payload, JweHeader header)
6262
byte[] encryptedSecretKeyBytes = RSA.wrapSecretKey(config.getEncryptionKey(), cek, "SHA-256");
6363
String encryptedKey = EncodingUtils.base64UrlEncode(encryptedSecretKeyBytes);
6464

65-
byte[] iv = AESEncryption.generateIv().getIV();
65+
byte[] iv = AESEncryption.generateIv(config.getIVSize()).getIV();
6666
byte[] payloadBytes = payload.getBytes();
6767
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
6868

src/test/java/com/mastercard/developer/encryption/FieldLevelEncryptionConfigBuilderTest.java

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@
77
import org.junit.rules.ExpectedException;
88

99
import static com.mastercard.developer.encryption.FieldLevelEncryptionConfig.FieldValueEncoding.HEX;
10+
import static org.hamcrest.MatcherAssert.assertThat;
11+
import static org.hamcrest.core.IsEqual.equalTo;
12+
import static org.junit.Assert.assertFalse;
1013

1114
public class FieldLevelEncryptionConfigBuilderTest {
1215

1316
@Rule
1417
public ExpectedException expectedException = ExpectedException.none();
1518

1619
@Test
17-
public void testBuild_Nominal() throws Exception {
20+
public void testBuild_Nominal_iv12() throws Exception {
1821
FieldLevelEncryptionConfig config = FieldLevelEncryptionConfigBuilder.aFieldLevelEncryptionConfig()
1922
.withEncryptionPath("$.payload", "$.encryptedPayload")
2023
.withEncryptionCertificate(TestUtils.getTestEncryptionCertificate())
@@ -35,6 +38,7 @@ public void testBuild_Nominal() throws Exception {
3538
.withIvFieldName("iv")
3639
.withIvHeaderName("x-iv")
3740
.withFieldValueEncoding(HEX)
41+
.withEncryptionIVSize(12)
3842
.build();
3943
Assert.assertNotNull(config);
4044
Assert.assertEquals(1, config.encryptionPaths.size());
@@ -56,6 +60,85 @@ public void testBuild_Nominal() throws Exception {
5660
Assert.assertEquals("oaepPaddingDigestAlgorithm", config.oaepPaddingDigestAlgorithmFieldName);
5761
Assert.assertEquals("x-oaep-padding-digest-algorithm", config.oaepPaddingDigestAlgorithmHeaderName);
5862
Assert.assertEquals(HEX, config.fieldValueEncoding);
63+
assertThat(config.getIVSize().intValue(),equalTo(12));
64+
}
65+
66+
@Test
67+
public void testBuild_Nominal_iv16() throws Exception {
68+
FieldLevelEncryptionConfig config = FieldLevelEncryptionConfigBuilder.aFieldLevelEncryptionConfig()
69+
.withEncryptionPath("$.payload", "$.encryptedPayload")
70+
.withEncryptionCertificate(TestUtils.getTestEncryptionCertificate())
71+
.withEncryptionCertificateFingerprint("97A2FFE9F0D48960EF31E87FCD7A55BF7843FB4A9EEEF01BDB6032AD6FEF146B")
72+
.withEncryptionKeyFingerprint("F806B26BC4870E26986C70B6590AF87BAF4C2B56BB50622C51B12212DAFF2810")
73+
.withEncryptionCertificateFingerprintFieldName("publicCertificateFingerprint")
74+
.withEncryptionCertificateFingerprintHeaderName("x-public-certificate-fingerprint")
75+
.withEncryptionKeyFingerprintFieldName("publicKeyFingerprint")
76+
.withEncryptionKeyFingerprintHeaderName("x-public-key-fingerprint")
77+
.withDecryptionPath("$.encryptedPayload", "$.payload")
78+
.withDecryptionKey(TestUtils.getTestDecryptionKey())
79+
.withOaepPaddingDigestAlgorithm("SHA-512")
80+
.withOaepPaddingDigestAlgorithmFieldName("oaepPaddingDigestAlgorithm")
81+
.withOaepPaddingDigestAlgorithmHeaderName("x-oaep-padding-digest-algorithm")
82+
.withEncryptedValueFieldName("encryptedValue")
83+
.withEncryptedKeyFieldName("encryptedKey")
84+
.withEncryptedKeyHeaderName("x-encrypted-key")
85+
.withIvFieldName("iv")
86+
.withIvHeaderName("x-iv")
87+
.withFieldValueEncoding(HEX)
88+
.withEncryptionIVSize(16)
89+
.build();
90+
Assert.assertNotNull(config);
91+
Assert.assertEquals(1, config.encryptionPaths.size());
92+
Assert.assertNotNull(config.encryptionCertificate);
93+
Assert.assertEquals("97A2FFE9F0D48960EF31E87FCD7A55BF7843FB4A9EEEF01BDB6032AD6FEF146B", config.encryptionCertificateFingerprint);
94+
Assert.assertEquals("F806B26BC4870E26986C70B6590AF87BAF4C2B56BB50622C51B12212DAFF2810", config.encryptionKeyFingerprint);
95+
Assert.assertEquals("publicCertificateFingerprint", config.encryptionCertificateFingerprintFieldName);
96+
Assert.assertEquals("x-public-certificate-fingerprint", config.encryptionCertificateFingerprintHeaderName);
97+
Assert.assertEquals("publicKeyFingerprint", config.encryptionKeyFingerprintFieldName);
98+
Assert.assertEquals("x-public-key-fingerprint", config.encryptionKeyFingerprintHeaderName);
99+
Assert.assertEquals(1, config.decryptionPaths.size());
100+
Assert.assertNotNull(config.decryptionKey);
101+
Assert.assertEquals("SHA-512", config.oaepPaddingDigestAlgorithm);
102+
Assert.assertEquals("encryptedValue", config.encryptedValueFieldName);
103+
Assert.assertEquals("encryptedKey", config.encryptedKeyFieldName);
104+
Assert.assertEquals("x-encrypted-key", config.encryptedKeyHeaderName);
105+
Assert.assertEquals("iv", config.ivFieldName);
106+
Assert.assertEquals("x-iv", config.ivHeaderName);
107+
Assert.assertEquals("oaepPaddingDigestAlgorithm", config.oaepPaddingDigestAlgorithmFieldName);
108+
Assert.assertEquals("x-oaep-padding-digest-algorithm", config.oaepPaddingDigestAlgorithmHeaderName);
109+
Assert.assertEquals(HEX, config.fieldValueEncoding);
110+
assertThat(config.getIVSize().intValue(),equalTo(16));
111+
}
112+
113+
@Test
114+
public void testBuild_FailedIV() throws Exception {
115+
try {
116+
FieldLevelEncryptionConfig config = FieldLevelEncryptionConfigBuilder.aFieldLevelEncryptionConfig()
117+
.withEncryptionPath("$.payload", "$.encryptedPayload")
118+
.withEncryptionCertificate(TestUtils.getTestEncryptionCertificate())
119+
.withEncryptionCertificateFingerprint("97A2FFE9F0D48960EF31E87FCD7A55BF7843FB4A9EEEF01BDB6032AD6FEF146B")
120+
.withEncryptionKeyFingerprint("F806B26BC4870E26986C70B6590AF87BAF4C2B56BB50622C51B12212DAFF2810")
121+
.withEncryptionCertificateFingerprintFieldName("publicCertificateFingerprint")
122+
.withEncryptionCertificateFingerprintHeaderName("x-public-certificate-fingerprint")
123+
.withEncryptionKeyFingerprintFieldName("publicKeyFingerprint")
124+
.withEncryptionKeyFingerprintHeaderName("x-public-key-fingerprint")
125+
.withDecryptionPath("$.encryptedPayload", "$.payload")
126+
.withDecryptionKey(TestUtils.getTestDecryptionKey())
127+
.withOaepPaddingDigestAlgorithm("SHA-512")
128+
.withOaepPaddingDigestAlgorithmFieldName("oaepPaddingDigestAlgorithm")
129+
.withOaepPaddingDigestAlgorithmHeaderName("x-oaep-padding-digest-algorithm")
130+
.withEncryptedValueFieldName("encryptedValue")
131+
.withEncryptedKeyFieldName("encryptedKey")
132+
.withEncryptedKeyHeaderName("x-encrypted-key")
133+
.withIvFieldName("iv")
134+
.withIvHeaderName("x-iv")
135+
.withFieldValueEncoding(HEX)
136+
.withEncryptionIVSize(23)
137+
.build();
138+
assertFalse("It should raise an exception, but it didn't", true);
139+
} catch ( IllegalArgumentException e) {
140+
assertThat(e.getMessage(), equalTo("Supported IV Sizes are either 12 or 16!"));
141+
}
59142
}
60143

61144
@Test

0 commit comments

Comments
 (0)