Skip to content

Commit df5f4cc

Browse files
Merge pull request #13 from Mastercard/feature/jwe-support
Introducing JWE encryption support
2 parents 5e8555f + a5cb49b commit df5f4cc

File tree

59 files changed

+2943
-932
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2943
-932
lines changed

pom.xml

Lines changed: 3 additions & 3 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.5.1-SNAPSHOT</version>
9+
<version>1.6.0-SNAPSHOT</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>
@@ -190,8 +190,8 @@
190190
<artifactId>maven-compiler-plugin</artifactId>
191191
<version>3.8.1</version>
192192
<configuration>
193-
<source>1.7</source>
194-
<target>1.7</target>
193+
<source>1.8</source>
194+
<target>1.8</target>
195195
</configuration>
196196
</plugin>
197197
</plugins>
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package com.mastercard.developer.encryption;
2+
3+
import java.security.PrivateKey;
4+
import java.security.cert.Certificate;
5+
import java.util.Collections;
6+
import java.util.Map;
7+
8+
public abstract class EncryptionConfig {
9+
10+
protected EncryptionConfig() {
11+
}
12+
13+
/**
14+
* The different methods of encryption
15+
*/
16+
public enum Scheme {
17+
LEGACY,
18+
JWE
19+
}
20+
21+
/**
22+
* The encryption scheme to be used
23+
*/
24+
Scheme scheme = Scheme.LEGACY;
25+
26+
/**
27+
* The SHA-256 hex-encoded digest of the key used for encryption (optional, the digest will be
28+
* automatically computed if this field is null or empty).
29+
* Example: "c3f8ef7053c4fb306f7476e7d1956f0aa992ff9dfdd5244b912a1d377ff3a84f"
30+
*/
31+
String encryptionKeyFingerprint;
32+
33+
/**
34+
* A certificate object whose public key will be used for encryption.
35+
*/
36+
Certificate encryptionCertificate;
37+
38+
/**
39+
* A private key object to be used for decryption.
40+
*/
41+
PrivateKey decryptionKey;
42+
43+
/**
44+
* A list of JSON paths to encrypt in request payloads.
45+
* Example:
46+
* <pre>
47+
* new HashMap<>() {
48+
* {
49+
* put("$.path.to.element.to.be.encrypted", "$.path.to.object.where.to.store.encryption.fields");
50+
* }
51+
* }
52+
* </pre>
53+
*/
54+
Map<String, String> encryptionPaths = Collections.emptyMap();
55+
56+
/**
57+
* A list of JSON paths to decrypt in response payloads.
58+
* Example:
59+
* <pre>
60+
* new HashMap<>() {
61+
* {
62+
* put("$.path.to.object.with.encryption.fields", "$.path.where.to.write.decrypted.element");
63+
* }
64+
* }
65+
* </pre>
66+
*/
67+
Map<String, String> decryptionPaths = Collections.emptyMap();
68+
69+
/**
70+
* The name of the payload field where to write/read the encrypted data value.
71+
*/
72+
String encryptedValueFieldName = null;
73+
74+
public String getEncryptionKeyFingerprint() { return encryptionKeyFingerprint; }
75+
76+
public Certificate getEncryptionCertificate() {
77+
return encryptionCertificate;
78+
}
79+
80+
public PrivateKey getDecryptionKey() {
81+
return decryptionKey;
82+
}
83+
84+
public Scheme getScheme() { return scheme; }
85+
86+
Map<String, String> getEncryptionPaths() {
87+
return encryptionPaths;
88+
}
89+
90+
Map<String, String> getDecryptionPaths() {
91+
return decryptionPaths;
92+
}
93+
94+
String getEncryptedValueFieldName() {
95+
return encryptedValueFieldName;
96+
}
97+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.mastercard.developer.encryption;
2+
3+
import com.jayway.jsonpath.JsonPath;
4+
5+
import java.security.MessageDigest;
6+
import java.security.NoSuchAlgorithmException;
7+
import java.security.PrivateKey;
8+
import java.security.cert.Certificate;
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
12+
import static com.mastercard.developer.utils.EncodingUtils.encodeBytes;
13+
import static com.mastercard.developer.utils.StringUtils.isNullOrEmpty;
14+
15+
abstract class EncryptionConfigBuilder {
16+
17+
Certificate encryptionCertificate;
18+
String encryptionKeyFingerprint;
19+
PrivateKey decryptionKey;
20+
FieldLevelEncryptionConfig.FieldValueEncoding fieldValueEncoding;
21+
Map<String, String> encryptionPaths = new HashMap<>();
22+
Map<String, String> decryptionPaths = new HashMap<>();
23+
String encryptedValueFieldName;
24+
25+
26+
void computeEncryptionKeyFingerprintWhenNeeded() throws EncryptionException {
27+
try {
28+
if (encryptionCertificate == null || !isNullOrEmpty(encryptionKeyFingerprint)) {
29+
// No encryption certificate set or key fingerprint already provided
30+
return;
31+
}
32+
byte[] keyFingerprintBytes = sha256digestBytes(encryptionCertificate.getPublicKey().getEncoded());
33+
encryptionKeyFingerprint = encodeBytes(keyFingerprintBytes, FieldLevelEncryptionConfig.FieldValueEncoding.HEX);
34+
} catch (Exception e) {
35+
throw new EncryptionException("Failed to compute encryption key fingerprint!", e);
36+
}
37+
}
38+
39+
static byte[] sha256digestBytes(byte[] bytes) throws NoSuchAlgorithmException {
40+
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
41+
messageDigest.update(bytes);
42+
return messageDigest.digest();
43+
}
44+
45+
void checkJsonPathParameterValues() {
46+
for (Map.Entry<String, String> entry : decryptionPaths.entrySet()) {
47+
if (!JsonPath.isPathDefinite(entry.getKey()) || !JsonPath.isPathDefinite(entry.getValue())) {
48+
throw new IllegalArgumentException("JSON paths for decryption must point to a single item!");
49+
}
50+
}
51+
52+
for (Map.Entry<String, String> entry : encryptionPaths.entrySet()) {
53+
if (!JsonPath.isPathDefinite(entry.getKey()) || !JsonPath.isPathDefinite(entry.getValue())) {
54+
throw new IllegalArgumentException("JSON paths for encryption must point to a single item!");
55+
}
56+
}
57+
}
58+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@ public class EncryptionException extends Exception {
55
public EncryptionException(String message, Throwable cause) {
66
super(message, cause);
77
}
8+
9+
public EncryptionException(String message) {
10+
super(message);
11+
}
812
}

0 commit comments

Comments
 (0)