Skip to content
This repository was archived by the owner on Feb 28, 2024. It is now read-only.

Commit e6d06eb

Browse files
Merge pull request #8 from Mastercard/feature/jwe-support
Adding JWE support
2 parents 1673c4f + f3d531b commit e6d06eb

18 files changed

+842
-80
lines changed

README.md

Lines changed: 176 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
- [Usage](#usage)
1818
- [Prerequisites](#prerequisites)
1919
- [Adding the Library to Your Project](#adding-the-libraries-to-your-project)
20-
- [Performing Field Level Encryption and Decryption](#performing-field-level-encryption-and-decryption)
20+
- [Performing Field Level Encryption and Decryption](#performing-payload-encryption-and-decryption)
2121
- [Integrating with OpenAPI Generator API Client Libraries](#integrating-with-openapi-generator-api-client-libraries)
2222

2323
## Overview <a name="overview"></a>
@@ -30,8 +30,8 @@ Ruby library for Mastercard API compliant payload encryption/decryption.
3030
- Truffle Ruby 1.0.0+
3131

3232
### References <a name="references"></a>
33-
34-
<img src="https://user-images.githubusercontent.com/3964455/55345820-c520a280-54a8-11e9-8235-407199fa1d97.png" alt="Encryption of sensitive data" width="75%" height="75%"/>
33+
* [JSON Web Encryption (JWE)](https://datatracker.ietf.org/doc/html/rfc7516)
34+
* [Securing Sensitive Data Using Payload Encryption](https://developer.mastercard.com/platform/documentation/security-and-authentication/securing-sensitive-data-using-payload-encryption/)
3535

3636
## Usage <a name="usage"></a>
3737

@@ -75,20 +75,171 @@ Import the library:
7575
```ruby
7676
require 'mcapi/encryption/openapi_interceptor' # to add the interceptor
7777
# or
78-
require 'mcapi/encryption/field_level_encryption' # to perform ad-hoc encryption/decryption
78+
require 'mcapi/encryption/field_level_encryption' # to perform ad-hoc Mastercard encryption/decryption
79+
require 'mcapi/encryption/jwe_encryption' # to perform ad-hoc JWE encryption/decryption
7980
```
8081

8182

8283

83-
### Performing Field Level Encryption and Decryption <a name="performing-field-level-encryption-and-decryption"></a>
84+
### Performing Payload Encryption and Decryption <a name="performing-payload-encryption-and-decryption"></a>
8485

8586
- [Introduction](#introduction)
86-
- [Configuring the Field Level Encryption](#configuring-the-field-level-encryption)
87-
- [Performing Encryption](#performing-encryption)
88-
- [Performing Decryption](#performing-decryption)
87+
- [JWE Encryption and Decryption](#jwe-encryption-and-decryption)
88+
- [Mastercard Encryption and Decryption](#mastercard-encryption-and-decryption)
8989

9090
#### Introduction <a name="introduction"></a>
9191

92+
This library supports two types of encryption/decryption, both of which support field level and entire payload encryption: JWE encryption and what the library refers to as Field Level Encryption (Mastercard encryption), a scheme used by many services hosted on Mastercard Developers before the library added support for JWE.
93+
94+
#### JWE Encryption and Decryption <a name="jwe-encryption-and-decryption"></a>
95+
96+
+ [Introduction](#jwe-introduction)
97+
+ [Configuring the JWE Encryption](#configuring-the-jwe-encryption)
98+
+ [Performing JWE Encryption](#performing-jwe-encryption)
99+
+ [Performing JWE Decryption](#performing-jwe-decryption)
100+
101+
##### • Introduction <a name="jwe-introduction"></a>
102+
103+
This library uses [JWE compact serialization](https://datatracker.ietf.org/doc/html/rfc7516#section-7.1) for the encryption of sensitive data.
104+
The core methods responsible for payload encryption and decryption are `encrypt` and `decrypt` in the `JweEncryption` class.
105+
106+
- `encrypt()` usage:
107+
108+
```ruby
109+
jwe = McAPI::Encryption::JweEncryption.new(@config)
110+
encrypted_request_payload = jwe.encrypt(endpoint, body)
111+
```
112+
113+
- `decrypt()` usage:
114+
115+
```ruby
116+
jwe = McAPI::Encryption::JweEncryption.new(@config)
117+
decrypted_response_payload = jwe.decrypt(encrypted_response_payload)
118+
```
119+
120+
#### Configuring the JWE Encryption <a name="configuring-the-jwe-encryption"></a>
121+
122+
`JweEncryption` needs a config object to instruct how to decrypt/decrypt the payloads. Example:
123+
124+
```json
125+
{
126+
"paths": [
127+
{
128+
"path": "/resource",
129+
"toEncrypt": [
130+
{
131+
"element": "path.to.foo",
132+
"obj": "path.to.encryptedFoo"
133+
}
134+
],
135+
"toDecrypt": [
136+
{
137+
"element": "path.to.encryptedFoo",
138+
"obj": "path.to.foo"
139+
}
140+
]
141+
}
142+
],
143+
"encryptedValueFieldName": "encryptedData",
144+
"encryptionCertificate": "./path/to/public.cert",
145+
"privateKey": "./path/to/your/private.key",
146+
}
147+
```
148+
149+
For all config options, please see:
150+
151+
- [Configuration object](https://github.com/Mastercard/client-encryption-ruby/wiki/Configuration-Object) for all config options
152+
153+
We have a predefined set of configurations to use with Mastercard services:
154+
155+
- [Service configurations](https://github.com/Mastercard/client-encryption-ruby/wiki/Service-Configurations-for-Client-Encryption-Ruby)
156+
157+
158+
#### Performing JWE Encryption <a name="performing-jwe-encryption"></a>
159+
160+
Call `JweEncryption.encrypt()` with a JSON request payload.
161+
162+
Example using the configuration [above](#configuring-the-jwe-encryption):
163+
164+
```ruby
165+
payload = JSON.generate({
166+
path: {
167+
to: {
168+
foo: {
169+
sensitiveField1: 'sensitiveValue1',
170+
sensitiveField2: 'sensitiveValue2'
171+
}
172+
}
173+
}
174+
})
175+
jwe = McAPI::Encryption::JweEncryption.new(@config)
176+
request_payload = jwe.encrypt("/resource", header, payload)
177+
```
178+
179+
Output:
180+
181+
```json
182+
{
183+
"path": {
184+
"to": {
185+
"encryptedFoo": {
186+
"encryptedValue": "eyJraWQiOiI3NjFiMDAzYzFlYWRlM….Y+oPYKZEMTKyYcSIVEgtQw"
187+
}
188+
}
189+
}
190+
}
191+
```
192+
193+
#### Performing JWE Decryption <a name="performing-jwe-decryption"></a>
194+
195+
Call `JweEncryption.decrypt()` with an (encrypted) `response` object with the following fields:
196+
197+
- `body`: json payload
198+
- `request.url`: requesting url
199+
200+
Example using the configuration [above](#configuring-the-jwe-encryption):
201+
202+
```ruby
203+
response = {}
204+
response[:request] = { url: '/resource1' }
205+
response[:body] =
206+
{
207+
"path": {
208+
"to": {
209+
"encryptedFoo": {
210+
"encryptedValue": "eyJraWQiOiI3NjFiMDAzYzFlYWRlM….Y+oPYKZEMTKyYcSIVEgtQw"
211+
}
212+
}
213+
}
214+
}
215+
jwe = McAPI::Encryption::JweEncryption.new(@config)
216+
response_payload = jwe.decrypt(response)
217+
```
218+
219+
Output:
220+
221+
```json
222+
{
223+
"path": {
224+
"to": {
225+
"foo": {
226+
"sensitiveField1": "sensitiveValue1",
227+
"sensitiveField2": "sensitiveValue2"
228+
}
229+
}
230+
}
231+
}
232+
```
233+
234+
#### Mastercard Encryption and Decryption <a name="mastercard-encryption-and-decryption"></a>
235+
236+
- [Introduction](#mastercard-introduction)
237+
- [Configuring the Mastercard Encryption](#configuring-the-mastercard-encryption)
238+
- [Performing Mastercard Encryption](#performing-mastercard-encryption)
239+
- [Performing Mastercard Decryption](#performing-mastercard-decryption)
240+
241+
#### Introduction <a name="mastercard-introduction"></a>
242+
92243
The core methods responsible for payload encryption and decryption are `encrypt` and `decrypt` in the `FieldLevelEncryption` class.
93244

94245
- `encrypt()` usage:
@@ -105,7 +256,7 @@ fle = McAPI::Encryption::FieldLevelEncryption.new(@config)
105256
decrypted_response_payload = fle.decrypt(encrypted_response_payload)
106257
```
107258

108-
#### Configuring the Field Level Encryption <a name="configuring-the-field-level-encryption"></a>
259+
#### Configuring the Mastercard Encryption <a name="configuring-the-mastercard-encryption"></a>
109260

110261
`FieldLevelEncryption` needs a config object to instruct how to decrypt/decrypt the payloads. Example:
111262

@@ -148,11 +299,11 @@ We have a predefined set of configurations to use with Mastercard services:
148299

149300

150301

151-
#### Performing Encryption <a name="performing-encryption"></a>
302+
#### Performing Mastercard Encryption <a name="performing-mastercard-encryption"></a>
152303

153304
Call `FieldLevelEncryption.encrypt()` with a JSON request payload, and optional `header` object.
154305

155-
Example using the configuration [above](#configuring-the-field-level-encryption):
306+
Example using the configuration [above](#configuring-the-mastercard-encryption):
156307

157308
```ruby
158309
payload = JSON.generate({
@@ -187,15 +338,15 @@ Output:
187338
}
188339
```
189340

190-
#### Performing Decryption <a name="performing-decryption"></a>
341+
#### Performing Mastercard Decryption <a name="performing-mastercard-decryption"></a>
191342

192343
Call `FieldLevelEncryption.decrypt()` with an (encrypted) `response` object with the following fields:
193344

194345
- `body`: json payload
195346
- `request.url`: requesting url
196347
- `header`: *optional*, header object
197348

198-
Example using the configuration [above](#configuring-the-field-level-encryption):
349+
Example using the configuration [above](#configuring-the-mastercard-encryption):
199350

200351
```ruby
201352
response = {}
@@ -240,9 +391,13 @@ It provides generators and library templates for supporting multiple languages a
240391

241392
The **client-encryption-ruby** library provides a method you can use to integrate the OpenAPI generated client with this library:
242393
```ruby
394+
# JWE Encryption
395+
McAPI::Encryption::OpenAPIInterceptor.install_jwe_encryption(open_api_client, config)
396+
397+
# Mastercard Encryption
243398
McAPI::Encryption::OpenAPIInterceptor.install_field_level_encryption(open_api_client, config)
244399
```
245-
This method will add the field level encryption in the generated OpenApi client, taking care of encrypting request and decrypting response payloads, but also of updating HTTP headers when needed, automatically, without manually calling `encrypt()`/`decrypt()` functions for each API request or response.
400+
The above methods will handle the encryption in the generated OpenApi client, taking care of encrypting request and decrypting response payloads, but also of updating HTTP headers when needed, automatically, without manually calling `encrypt()`/`decrypt()` functions for each API request or response.
246401

247402
##### OpenAPI Generator <a name="openapi-generator"></a>
248403

@@ -271,15 +426,20 @@ To use it:
271426
require_relative './out/generated_open_apiclient' #import generated OpenAPI client
272427
```
273428

274-
3. Install the field level encryption in the generated client:
429+
3. Install the Mastercard/JWE encryption in the generated client:
275430

276431
```ruby
277432
# Read the service configuration obj
278433
@config = File.read('./config.json')
279434
# Create a new instance of the generated client
280435
@api_client = client::ApiClient.new
281-
# Enable field level encryption
436+
437+
# Use 1 of the below 2 methods (depending on the encryption type) to enable encryption
438+
# Enable Mastercard encryption
282439
McAPI::Encryption::OpenAPIInterceptor.install_field_level_encryption(@api_client, @config)
440+
441+
# Enable JWE encryption
442+
McAPI::Encryption::OpenAPIInterceptor.install_jwe_encryption(@api_client, @config)
283443
```
284444

285445
4. Use the `api_client` object with the Field Level Encryption enabled:

0 commit comments

Comments
 (0)