Skip to content

Commit 295c84e

Browse files
committed
licence, readme, setup and requirements
1 parent 3c90075 commit 295c84e

File tree

5 files changed

+384
-0
lines changed

5 files changed

+384
-0
lines changed

.travis.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
dist: xenial # required for Python >= 3.7
2+
language: python
3+
git:
4+
depth: false # "Shallow clone detected during the analysis"
5+
matrix:
6+
fast_finish: true
7+
include:
8+
- python: "3.6"`
9+
- python: "3.7"`
10+
env:
11+
# Do not run analysis on PR (secure env variables like SONAR_TOKEN are not always available)
12+
- WITH_SONAR_ANALYSIS=$([ "$TRAVIS_PULL_REQUEST" = "false" ] && echo true || echo false)
13+
14+
install:
15+
- pip3 install -r requirements.txt
16+
- pip3 install .
17+
- |
18+
test "$WITH_SONAR_ANALYSIS" = "true" \
19+
&& wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION.zip \
20+
&& unzip sonar-scanner-cli-$SONAR_SCANNER_VERSION.zip || echo 'Skipping Sonar Scanner installation'
21+
# command to run tests
22+
script:
23+
- pytest
24+
after_success:
25+
- |
26+
test "$WITH_SONAR_ANALYSIS" = "true" && sonar-scanner-$SONAR_SCANNER_VERSION/bin/sonar-scanner \
27+
-Dsonar.projectName=$SONAR_PROJECT_NAME \
28+
-Dsonar.projectKey=$SONAR_PROJECT_KEY \
29+
-Dsonar.organization=$SONAR_ORGANIZATION_KEY \
30+
-Dsonar.sources=./client_encryption \
31+
-Dsonar.tests=./tests \
32+
-Dsonar.testExecutionReportPaths=tests.xml \
33+
-Dsonar.python.coverage.reportPaths=coverage.xml \
34+
-Dsonar.host.url=$SONAR_URL \
35+
-Dsonar.login=$SONAR_TOKEN || echo 'Skipping Sonar Scanner execution'

LICENCE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Mastercard
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
# client-encryption-python
2+
3+
[![](https://api.travis-ci.org/Mastercard/client-encryption-python.svg?branch=master)](https://api.travis-ci.org/Mastercard/client-encryption-python)
4+
[![](https://sonarcloud.io/api/project_badges/measure?project=Mastercard_client-encryption-python&metric=alert_status)](https://sonarcloud.io/dashboard?id=Mastercard_client-encryption-python)
5+
[![](https://sonarcloud.io/api/project_badges/measure?project=Mastercard_client-encryption-python&metric=coverage)](https://sonarcloud.io/dashboard?id=Mastercard_client-encryption-python)
6+
[![](https://sonarcloud.io/api/project_badges/measure?project=Mastercard_client-encryption-python&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=Mastercard_client-encryption-python)
7+
[![](https://img.shields.io/pypy/v/mastercard-client-encryption.svg)](https://pypi.org/project/mastercard-client-encryption)
8+
[![](https://img.shields.io/badge/license-MIT-yellow.svg)](https://github.com/Mastercard/client-encryption-python/blob/master/LICENSE)
9+
10+
## Table of Contents
11+
- [Overview](#overview)
12+
* [Compatibility](#compatibility)
13+
* [References](#references)
14+
- [Usage](#usage)
15+
* [Prerequisites](#prerequisites)
16+
* [Adding the Library to Your Project](#adding-the-library-to-your-project)
17+
* [Performing Field Level Encryption and Decryption](#performing-field-level-encryption-and-decryption)
18+
* [Integrating with OpenAPI Generator API Client Libraries](#integrating-with-openapi-generator-api-client-libraries)
19+
20+
21+
## Overview <a name="overview"></a>
22+
This is the Python version of the Mastercard compliant payload encryption/decryption.
23+
24+
### Compatibility <a name="compatibility"></a>
25+
Python 3.6, 3.7
26+
27+
### References <a name="references"></a>
28+
29+
<img src="https://user-images.githubusercontent.com/3964455/55345820-c520a280-54a8-11e9-8235-407199fa1d97.png" alt="Encryption of sensitive data" width="75%" height="75%"/>
30+
31+
## Usage <a name="usage"></a>
32+
33+
### Prerequisites <a name="prerequisites"></a>
34+
35+
Before using this library, you will need to set up a project in the [Mastercard Developers Portal](https://developer.mastercard.com).
36+
37+
As part of this set up, you'll receive:
38+
39+
- A public request encryption certificate (aka _Client Encryption Keys_)
40+
- A private response decryption key (aka _Mastercard Encryption Keys_)
41+
42+
### Installation <a name="adding-the-libraries-to-your-project"></a>
43+
44+
If you want to use **mastercard-client-encryption** with [Python](https://www.python.org/), it is available through `pypy`:
45+
46+
- [https://pypi.org/project/mastercard-client-encryption](https://pypi.org/project/mastercard-client-encryption)
47+
48+
**Adding the library to your project**
49+
50+
Install the library by pip:
51+
52+
```bash
53+
$ pip install mastercard-client-encryption
54+
```
55+
56+
Or clone it from git:
57+
58+
```bash
59+
$ git clone https://github.com/Mastercard/client-encryption-python.git
60+
```
61+
62+
and then execute from the repo folder:
63+
64+
```bash
65+
$ python3 setup.py install
66+
```
67+
68+
You can then use it as a regular module:
69+
70+
```python
71+
from client_encryption.field_level_encryption_config import FieldLevelEncryptionConfig
72+
from client_encryption.field_level_encryption import encrypt_payload, decrypt_payload
73+
```
74+
75+
### Performing Field Level Encryption and Decryption <a name="performing-field-level-encryption-and-decryption"></a>
76+
77+
- [Introduction](#introduction)
78+
- [Configuring the Field Level Encryption](#configuring-the-field-level-encryption)
79+
- [Performing Encryption](#performing-encryption)
80+
- [Performing Decryption](#performing-decryption)
81+
82+
#### Introduction <a name="introduction"></a>
83+
84+
The core methods responsible for payload encryption and decryption are `encrypt_payload` and `decrypt_payload` in the `field_level_encryption` module.
85+
86+
- `encrypt_payload()` usage:
87+
88+
```python
89+
config = FieldLevelEncryptionConfig(config_dictionary)
90+
encrypted_request_payload = encrypt_payload(body, config)
91+
```
92+
93+
- `decrypt_payload()` usage:
94+
95+
```python
96+
config = FieldLevelEncryptionConfig(config_dictionary)
97+
decrypted_response_payload = decrypt_payload(body, config)
98+
```
99+
100+
#### Configuring the Field Level Encryption <a name="configuring-the-field-level-encryption"></a>
101+
102+
`field_level_encryption` needs a config dictionary to instruct how to decrypt/decrypt the payloads. Example:
103+
104+
```json
105+
{
106+
"paths": {
107+
"$": {
108+
"toEncrypt": {
109+
"element": "path.to.foo",
110+
"obj": "path.to.encryptedFoo"
111+
},
112+
"toDecrypt": {
113+
"element": "path.to.encryptedFoo",
114+
"obj": "path.to.foo"
115+
}
116+
}
117+
},
118+
"ivFieldName": "iv",
119+
"encryptedKeyFieldName": "encryptedKey",
120+
"encryptedValueFieldName": "encryptedData",
121+
"dataEncoding": "hex",
122+
"encryptionCertificate": "./path/to/public.cert",
123+
"decryptionKey": "./path/to/your/private.key",
124+
"oaepPaddingDigestAlgorithm": "SHA256"
125+
}
126+
```
127+
128+
The above can be either stored to a file or passed to 'FieldLevelEncryptionConfig' as dictionary:
129+
```python
130+
config_dictionary = {"paths": {...},
131+
(...)
132+
"decryptionKey": "./path/to/your/private.key",
133+
"oaepPaddingDigestAlgorithm": "SHA256"
134+
}
135+
config = FieldLevelEncryptionConfig(config_dictionary)
136+
137+
config_file_path = "./config.json"
138+
config = FieldLevelEncryptionConfig(config_file_path)
139+
```
140+
141+
For all config options, please see:
142+
143+
- [Configuration object](https://github.com/Mastercard/client-encryption-python/wiki/Configuration-Object) for all config options
144+
145+
We have a predefined set of configurations to use with Mastercard services:
146+
147+
- [Service configurations](https://github.com/Mastercard/client-encryption-python/wiki/Mastercard-Services-Configuration) wiki page
148+
149+
150+
151+
#### Performing Encryption <a name="performing-encryption"></a>
152+
153+
Call `field_level_encryption.encrypt_payload()` with a JSON (dict) request payload, and optional `params` object.
154+
155+
Example using the configuration [above](#configuring-the-field-level-encryption):
156+
157+
```python
158+
from client_encryption.session_key_params import SessionKeyParams
159+
160+
payload = {
161+
path: {
162+
to: {
163+
foo: {
164+
sensitiveField1: 'sensitiveValue1',
165+
sensitiveField2: 'sensitiveValue2'
166+
}
167+
}
168+
}
169+
}
170+
171+
params = SessionKeyParams.generate(conf) # optional
172+
request_payload = encrypt_payload(payload, config, params)
173+
```
174+
175+
Output:
176+
177+
```json
178+
{
179+
"path": {
180+
"to": {
181+
"encryptedFoo": {
182+
"iv": "7f1105fb0c684864a189fb3709ce3d28",
183+
"encryptedKey": "67f467d1b653d98411a0c6d3c(...)ffd4c09dd42f713a51bff2b48f937c8",
184+
"encryptedData": "b73aabd267517fc09ed72455c2(...)dffb5fa04bf6e6ce9ade1ff514ed6141",
185+
"publicKeyFingerprint": "80810fc13a8319fcf0e2e(...)82cc3ce671176343cfe8160c2279",
186+
"oaepHashingAlgorithm": "SHA256"
187+
}
188+
}
189+
}
190+
}
191+
```
192+
193+
#### Performing Decryption <a name="performing-decryption"></a>
194+
195+
Call `field_level_encryption.decrypt_payload()` with a JSON (dict) encrypted response payload.
196+
197+
Example using the configuration [above](#configuring-the-field-level-encryption):
198+
199+
```python
200+
response = {
201+
path: {
202+
to: {
203+
encryptedFoo: {
204+
iv: 'e5d313c056c411170bf07ac82ede78c9',
205+
encryptedKey: 'e3a56746c0f9109d18b3a2652b76(...)f16d8afeff36b2479652f5c24ae7bd',
206+
encryptedData: '809a09d78257af5379df0c454dcdf(...)353ed59fe72fd4a7735c69da4080e74f',
207+
oaepHashingAlgorithm: 'SHA256',
208+
publicKeyFingerprint: '80810fc13a8319fcf0e2e(...)3ce671176343cfe8160c2279'
209+
}
210+
}
211+
}
212+
}
213+
214+
response_payload = decrypt_payload(response, config)
215+
216+
```
217+
218+
Output:
219+
220+
```json
221+
{
222+
"path": {
223+
"to": {
224+
"foo": {
225+
"sensitiveField1": "sensitiveValue1",
226+
"sensitiveField2": "sensitiveValue2"
227+
}
228+
}
229+
}
230+
}
231+
```
232+
233+
### Integrating with OpenAPI Generator API Client Libraries <a name="integrating-with-openapi-generator-api-client-libraries"></a>
234+
235+
[OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator) generates API client libraries from [OpenAPI Specs](https://github.com/OAI/OpenAPI-Specification).
236+
It provides generators and library templates for supporting multiple languages and frameworks.
237+
238+
The **client-encryption-python** library provides a method you can use to integrate the OpenAPI generated client with this library:
239+
```python
240+
from client_encryption.field_level_encryption_config import FieldLevelEncryptionConfig
241+
from client_encryption.api_encryption import add_encryption_layer
242+
243+
api_encryption.add_encryption_layer(api_client, config)
244+
```
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_payload()`/`decrypt_payload()` functions for each API request or response.
246+
247+
##### OpenAPI Generator <a name="openapi-generator"></a>
248+
249+
OpenAPI client can be generated, starting from your OpenAPI Spec / Swagger using the following command:
250+
251+
```shell
252+
java -jar openapi-generator-cli.jar generate -i openapi-spec.yaml -l python -o out
253+
```
254+
255+
Client library will be generated in the `out` folder.
256+
257+
See also:
258+
259+
- [OpenAPI Generator (executable)](https://mvnrepository.com/artifact/org.openapitools/openapi-generator-cli)
260+
261+
##### Usage of the `api_encryption.add_encryption_layer`:
262+
263+
To use it:
264+
265+
1. Generate the OpenAPI client, as [above](#openapi-generator)
266+
267+
2. Import the **mastercard-client-encryption** module and the generated swagger ApiClient
268+
269+
```python
270+
from client_encryption.field_level_encryption_config import FieldLevelEncryptionConfig
271+
from client_encryption.api_encryption import add_encryption_layer
272+
from swagger_client.api_client import ApiClient # import generated swagger ApiClient
273+
```
274+
275+
3. Add the field level encryption layer to the generated client:
276+
277+
```python
278+
# Read the service configuration file
279+
config_file_path = "./config.json"
280+
config = FieldLevelEncryptionConfig(config_file_path)
281+
# Create a new instance of the generated client
282+
api_client = ApiClient()
283+
# Enable field level encryption
284+
api_encryption.add_encryption_layer(api_client, config)
285+
```
286+
287+
4. Use the `ApiClient` instance with the Field Level Encryption enabled:
288+
289+
Example:
290+
291+
```python
292+
request_body = {...}
293+
response =MyServiceApi(api_client).do_some_action_post(body=request_body)
294+
# requests and responses will be automatically encrypted and decrypted
295+
# accordingly with the configuration object used
296+
297+
# ... use the (decrypted) response object here ...
298+
decrypted = response.json()
299+
300+
```

requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pycryptodome==3.8.1
2+
pyOpenSSL==19.0.0
3+
setuptools>=39.0.1

setup.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from setuptools import setup
2+
3+
exec(open('client_encryption/version.py').read())
4+
5+
setup(name='mastercard-client-encryption',
6+
python_requires='>=3.5.4',
7+
version=__version__,
8+
description='Mastercard Client encryption.',
9+
long_description='Library for encrypting a Mastercard API compliant request.',
10+
author='Mastercard',
11+
url='https://github.com/Mastercard/client-encryption-python',
12+
license='MIT',
13+
packages=['client_encryption'],
14+
classifiers=[
15+
'Development Status :: 2 - Pre-Alpha',
16+
'Intended Audience :: Developers',
17+
'Natural Language :: English',
18+
'Operating System :: OS Independent',
19+
'Programming Language :: Python :: 3.6',
20+
'Programming Language :: Python :: 3.7',
21+
'Topic :: Software Development :: Libraries :: Python Modules'
22+
],
23+
tests_require=['coverage'],
24+
install_requires=['pycryptodome>=3.8.1', 'pyOpenSSL>=19.0.0', 'setuptools>=39.0.1']
25+
)

0 commit comments

Comments
 (0)