Skip to content

Commit 919f7aa

Browse files
committed
Fixed #8 and #9, code clean-up
1 parent de64e1c commit 919f7aa

File tree

8 files changed

+196
-87
lines changed

8 files changed

+196
-87
lines changed

Mastercard.Developer.ClientEncryption.Core/Encryption/JWE/JweEncryption.cs

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,26 @@ namespace Mastercard.Developer.ClientEncryption.Core.Encryption.JWE
88
{
99
public static class JweEncryption
1010
{
11-
private const string ALGORITHM = "RSA-OAEP-256";
12-
private const string ENCRYPTION = "A256GCM";
13-
private const string CONTENT_TYPE = "application/json";
11+
private const string Algorithm = "RSA-OAEP-256";
12+
private const string Encryption = "A256GCM";
13+
private const string ContentType = "application/json";
1414

1515
public static string EncryptPayload(string payload, JweConfig config)
1616
{
1717
try
1818
{
1919
// Parse the given payload
20-
JToken json = JObject.Parse(payload);
20+
var payloadToken = JToken.Parse(payload);
2121

2222
// Encrypt
2323
foreach (var entry in config.EncryptionPaths)
2424
{
25-
string jsonPathIn = entry.Key;
26-
string jsonPathOut = entry.Value;
27-
json = EncryptPayloadPath(json, jsonPathIn, jsonPathOut, config);
25+
var jsonPathIn = entry.Key;
26+
var jsonPathOut = entry.Value;
27+
payloadToken = EncryptPayloadPath(payloadToken, jsonPathIn, jsonPathOut, config);
2828
}
2929

30-
return json.ToString();
30+
return payloadToken.ToString();
3131
}
3232
catch (Exception ex)
3333
{
@@ -40,16 +40,16 @@ public static string DecryptPayload(string payload, JweConfig config)
4040
try
4141
{
4242
// Parse the given payload
43-
JToken json = JObject.Parse(payload);
43+
var payloadToken = JToken.Parse(payload);
4444

4545
// Perform decryption
4646
foreach (var entry in config.DecryptionPaths)
4747
{
48-
string jsonPathIn = entry.Key;
49-
string jsonPathOut = entry.Value;
50-
json = DecryptPayloadPath(json, jsonPathIn, jsonPathOut, config);
48+
var jsonPathIn = entry.Key;
49+
var jsonPathOut = entry.Value;
50+
payloadToken = DecryptPayloadPath(payloadToken, jsonPathIn, jsonPathOut, config);
5151
}
52-
return json.ToString();
52+
return payloadToken.ToString();
5353
}
5454
catch (Exception ex)
5555
{
@@ -59,26 +59,26 @@ public static string DecryptPayload(string payload, JweConfig config)
5959

6060
private static JToken DecryptPayloadPath(JToken payload, string jsonPathIn, string jsonPathOut, JweConfig config)
6161
{
62-
JToken token = payload.SelectToken(jsonPathIn);
63-
if (JsonUtils.IsNullOrEmptyJson( token ))
62+
var token = payload.SelectToken(jsonPathIn);
63+
if (JsonUtils.IsNullOrEmptyJson(token))
6464
{
6565
// Nothing to decrypt
6666
return payload;
6767
}
6868

6969
// Read and remove encrypted data and encryption fields at the given JSON path
70-
string encryptedValue = ReadAndDeleteJsonKey(payload, token, config.EncryptedValueFieldName);
70+
var encryptedValue = ReadAndDeleteJsonKey(payload, token, config.EncryptedValueFieldName);
7171
if (string.IsNullOrEmpty(encryptedValue))
7272
{
7373
// Nothing to decrypt
7474
return payload;
7575
}
76-
JweObject jweObject = JweObject.Parse(encryptedValue);
77-
string decryptedValue = jweObject.Decrypt(config);
76+
var jweObject = JweObject.Parse(encryptedValue);
77+
var decryptedValue = jweObject.Decrypt(config);
7878

7979
if ("$".Equals(jsonPathOut))
8080
{
81-
return JObject.Parse(decryptedValue);
81+
return JToken.Parse(decryptedValue);
8282
}
8383

8484
JsonUtils.CheckOrCreateOutObject(payload, jsonPathOut);
@@ -95,30 +95,28 @@ private static JToken DecryptPayloadPath(JToken payload, string jsonPathIn, stri
9595

9696
private static string ReadAndDeleteJsonKey(JToken context, JToken token, string key)
9797
{
98-
if (!string.IsNullOrEmpty(key))
98+
if (string.IsNullOrEmpty(key)) return token.ToString();
99+
var value = context.SelectToken(key);
100+
if (null != value && null != value.Parent)
99101
{
100-
var value = context.SelectToken(key);
101-
if (null != value && null != value.Parent)
102-
{
103-
value.Parent.Remove();
104-
}
102+
value.Parent.Remove();
105103
}
106104
return token.ToString();
107105
}
108106

109107
private static JToken EncryptPayloadPath(JToken json, string jsonPathIn, string jsonPathOut, JweConfig config)
110108
{
111-
JToken token = json.SelectToken(jsonPathIn);
109+
var token = json.SelectToken(jsonPathIn);
112110
if (JsonUtils.IsNullOrEmptyJson(token))
113111
{
114112
// Nothing to encrypt
115113
return json;
116114
}
117115

118116
// Encode and encrypt
119-
string inJsonString = JsonUtils.SanitizeJson(token.ToString(Formatting.None));
120-
JweHeader header = new JweHeader(ALGORITHM, ENCRYPTION, config.EncryptionKeyFingerprint, CONTENT_TYPE);
121-
string encrypted = JweObject.Encrypt(config, inJsonString, header);
117+
var inJsonString = JsonUtils.SanitizeJson(token.ToString(Formatting.None));
118+
var header = new JweHeader(Algorithm, Encryption, config.EncryptionKeyFingerprint, ContentType);
119+
var encrypted = JweObject.Encrypt(config, inJsonString, header);
122120

123121
// Delete data in the clear
124122
if ("$".Equals(jsonPathIn))
@@ -134,7 +132,7 @@ private static JToken EncryptPayloadPath(JToken json, string jsonPathIn, string
134132
JsonUtils.CheckOrCreateOutObject(json, jsonPathOut);
135133
var outJsonToken = json.SelectToken(jsonPathOut) as JObject;
136134
JsonUtils.AddOrReplaceJsonKey(outJsonToken, config.EncryptedValueFieldName, encrypted);
137-
return outJsonToken;
135+
return json;
138136
}
139137
}
140138
}

Mastercard.Developer.ClientEncryption.Core/Encryption/JWE/JweHeader.cs

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Text;
1+
using System.Text;
32
using Newtonsoft.Json.Linq;
43
using Mastercard.Developer.ClientEncryption.Core.Utils;
54
#pragma warning disable 1591 // "Missing XML comment for publicly visible type or member."
@@ -8,15 +7,15 @@ namespace Mastercard.Developer.ClientEncryption.Core.Encryption.JWE
87
{
98
internal sealed class JweHeader
109
{
11-
const string ALGORITHM = "alg";
12-
const string KEY_ID = "kid";
13-
const string ENCRYPTION_ALGORITHM = "enc";
14-
const string CONTENT_TYPE = "cty";
10+
private const string Algorithm = "alg";
11+
private const string KeyId = "kid";
12+
private const string EncryptionAlgorithm = "enc";
13+
private const string ContentType = "cty";
1514

16-
public string Enc { get; private set; }
17-
public string Kid { get; private set; }
18-
public string Alg { get; private set; }
19-
public string Cty { get; private set; }
15+
public string Enc { get; }
16+
public string Kid { get; }
17+
public string Alg { get; }
18+
public string Cty { get; }
2019

2120
public JweHeader(string alg, string enc, string kid, string cty)
2221
{
@@ -26,32 +25,27 @@ public JweHeader(string alg, string enc, string kid, string cty)
2625
Cty = cty;
2726
}
2827

29-
public JObject Json
30-
{
31-
get
32-
{
33-
return new JObject(
34-
new JProperty(KEY_ID, Kid),
35-
new JProperty(CONTENT_TYPE, Cty),
36-
new JProperty(ENCRYPTION_ALGORITHM, Enc),
37-
new JProperty(ALGORITHM, Alg)
38-
);
39-
}
40-
}
28+
public JObject Json =>
29+
new JObject(
30+
new JProperty(KeyId, Kid),
31+
new JProperty(ContentType, Cty),
32+
new JProperty(EncryptionAlgorithm, Enc),
33+
new JProperty(Algorithm, Alg)
34+
);
4135

42-
public static JweHeader Parse(String encoded)
36+
public static JweHeader Parse(string encoded)
4337
{
4438
// Decode and parse the string
45-
byte[] decoded = Base64Utils.URLDecode(encoded);
46-
string json = Encoding.UTF8.GetString(decoded);
47-
JObject jobject = JObject.Parse(json);
39+
var decoded = Base64Utils.URLDecode(encoded);
40+
var json = Encoding.UTF8.GetString(decoded);
41+
var jobject = JObject.Parse(json);
4842

4943
// Wrap it up
5044
return new JweHeader(
51-
((string)jobject[ALGORITHM]),
52-
((string)jobject[ENCRYPTION_ALGORITHM]),
53-
((string)jobject[KEY_ID]),
54-
((string)jobject[CONTENT_TYPE])
45+
((string)jobject[Algorithm]),
46+
((string)jobject[EncryptionAlgorithm]),
47+
((string)jobject[KeyId]),
48+
((string)jobject[ContentType])
5549
);
5650
}
5751
}

Mastercard.Developer.ClientEncryption.Core/Encryption/JWE/JweObject.cs

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,52 +21,51 @@ internal class JweObject
2121

2222
public string Decrypt(JweConfig config)
2323
{
24-
byte[] unwrappedKey = RsaEncryption.UnwrapSecretKey(config, Base64Utils.URLDecode(EncryptedKey), "SHA-256");
24+
var unwrappedKey = RsaEncryption.UnwrapSecretKey(config, Base64Utils.URLDecode(EncryptedKey), "SHA-256");
2525
if (unwrappedKey == null)
2626
{
27-
throw new EncryptionException(String.Format("Failed to unwrap key {0}", EncryptedKey));
27+
throw new EncryptionException($"Failed to unwrap key {EncryptedKey}");
2828
}
2929

30-
string encryptionMethod = Header.Enc;
30+
var encryptionMethod = Header.Enc;
3131

3232
byte[] plaintext;
33-
if (A256GCM.Equals(encryptionMethod))
33+
switch (encryptionMethod)
3434
{
35-
plaintext = AesGcm.Decrypt(unwrappedKey, this);
36-
}
37-
else if (A128CBC_HS256.Equals(encryptionMethod))
38-
{
39-
plaintext = AesCbc.Decrypt(unwrappedKey, this);
40-
}
41-
else
42-
{
43-
throw new EncryptionException(String.Format("Encryption method {0} is not supported", encryptionMethod));
35+
case A256GCM:
36+
plaintext = AesGcm.Decrypt(unwrappedKey, this);
37+
break;
38+
case A128CBC_HS256:
39+
plaintext = AesCbc.Decrypt(unwrappedKey, this);
40+
break;
41+
default:
42+
throw new EncryptionException($"Encryption method {encryptionMethod} is not supported");
4443
}
4544
return Encoding.UTF8.GetString(plaintext);
4645
}
4746

48-
public static string Encrypt(JweConfig config, String payload, JweHeader header)
47+
public static string Encrypt(JweConfig config, string payload, JweHeader header)
4948
{
50-
byte[] cek = AesEncryption.GenerateCek(256);
51-
byte[] encryptedSecretKeyBytes = RsaEncryption.WrapSecretKey(config.EncryptionCertificate.GetRSAPublicKey(), cek, "SHA-256");
52-
string encryptedKey = Base64Utils.URLEncode(encryptedSecretKeyBytes);
49+
var cek = AesEncryption.GenerateCek(256);
50+
var encryptedSecretKeyBytes = RsaEncryption.WrapSecretKey(config.EncryptionCertificate.GetRSAPublicKey(), cek, "SHA-256");
51+
var encryptedKey = Base64Utils.URLEncode(encryptedSecretKeyBytes);
5352

54-
byte[] iv = AesEncryption.GenerateIV();
55-
byte[] payloadBytes = Encoding.UTF8.GetBytes(payload);
53+
var iv = AesEncryption.GenerateIV();
54+
var payloadBytes = Encoding.UTF8.GetBytes(payload);
5655

57-
string headerString = header.Json.ToString();
58-
string encodedHeader = Base64Utils.URLEncode(Encoding.UTF8.GetBytes(headerString));
59-
byte[] aad = Encoding.ASCII.GetBytes(encodedHeader);
56+
var headerString = header.Json.ToString();
57+
var encodedHeader = Base64Utils.URLEncode(Encoding.UTF8.GetBytes(headerString));
58+
var aad = Encoding.ASCII.GetBytes(encodedHeader);
6059

6160
var encrypted = AesGcm.Encrypt(cek, iv, payloadBytes, aad);
6261
return Serialize(encodedHeader, encryptedKey, Base64Utils.URLEncode(iv), Base64Utils.URLEncode(encrypted.Ciphertext), Base64Utils.URLEncode(encrypted.AuthTag));
6362
}
6463

65-
public static JweObject Parse(String encryptedPayload)
64+
public static JweObject Parse(string encryptedPayload)
6665
{
67-
string[] fields = encryptedPayload.Trim().Split('.');
66+
var fields = encryptedPayload.Trim().Split('.');
6867

69-
JweObject jweObject = new JweObject();
68+
var jweObject = new JweObject();
7069
jweObject.RawHeader = fields[0];
7170
jweObject.Header = JweHeader.Parse(jweObject.RawHeader);
7271
jweObject.EncryptedKey = fields[1];

Mastercard.Developer.ClientEncryption.Tests/Net4x/Mastercard.Developer.ClientEncryption.Tests.Net4x.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@
6363
<Compile Include="..\NetCore2\Encryption\JweConfigBuilderTest.cs">
6464
<Link>Encryption\JweConfigBuilderTest.cs</Link>
6565
</Compile>
66+
<Compile Include="..\NetCore2\Encryption\JWE\JweEncryptionTest.cs">
67+
<Link>Encryption\JWE\JweEncryptionTest.cs</Link>
68+
</Compile>
6669
<Compile Include="..\NetCore2\Interceptors\RestResponseDouble.cs">
6770
<Link>Interceptors\RestResponseDouble.cs</Link>
6871
</Compile>

Mastercard.Developer.ClientEncryption.Tests/Net5/Mastercard.Developer.ClientEncryption.Tests.Net5.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@
6060
</Compile>
6161
<Compile Include="..\NetCore2\Encryption\JWE\JweHeaderTest.cs">
6262
<Link>Encryption\JWE\JweHeaderTest.cs</Link>
63+
</Compile>
64+
<Compile Include="..\NetCore2\Encryption\JWE\JweEncryptionTest.cs">
65+
<Link>Encryption\JWE\JweEncryptionTest.cs</Link>
6366
</Compile>
6467
<Compile Include="..\NetCore2\Encryption\RSA\RsaEncryptionTest.cs">
6568
<Link>Encryption\RSA\RsaEncryptionTest.cs</Link>

0 commit comments

Comments
 (0)