Skip to content

Commit

Permalink
Merge pull request #30 from 420neshot/larky_AES_CCM_GCM
Browse files Browse the repository at this point in the history
New larky sample AES CCM-n-GCM
  • Loading branch information
mottersheadt committed Sep 12, 2022
2 parents bd8d0bd + 5ff5e36 commit 8f837ff
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 1 deletion.
55 changes: 55 additions & 0 deletions integrations/larky/crypto/AES_CCM_GCM/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# AES CCM and GCM sample of encryption in Larky

This sample includes:
1. Python script that generates an ectrypted message of an input data;
2. Larky test `.star` file that generates the same result of the same input data;
3. Ready-for-use YAML (Inbound Route) that produces the same result as previous scripts.

## Testing part:

#### 1. Python:

Python script includes all hard-coded inside. As a result, it prints the encrypted message:
```
$ python python_sample.py
>>> Encrypted GCM: YXNkNDU2ZmdoMDEyql2O8UB53Ux94KWoIaIDarnm+6xKaXL2FNfHl5XOCtbv590W5x6ISEI3
>>> GCM decrypted: b'{"card_number":"4111111111111111"}'
>>> Encrypted CCM: YXNkNDU2ZmdoMDEysNf+zbjlTcFG/q1TPyuLIJwELXp6pSwIx1bwpV8Zw92S6G2FpI3OpWEJ
>>> CCM decrypted: b'{"card_number":"4111111111111111"}'
```

#### 2. Larky test:

To be able to run Larky locally, you'll need to setup your local environment:
https://www.verygoodsecurity.com/docs/larky/test-larky-locally

Example of run:

<img width="1364" alt="image" src="https://user-images.githubusercontent.com/78090218/189484115-04cfb575-f39c-4e55-9f9e-1d0095650e63.png">

#### 3. YAML file:

Upload the YAML to your vault and run:
```
curl https://tntbmt67sc7.sandbox.verygoodproxy.com/post -k \
-H "Content-type: application/json" \
-d '{"card_number":"4111111111111111"}'
```

Example of response:
```
"json": {
"CCM": "YXNkNDU2ZmdoMDEysNf+zbjlTcFG/q1TPyuLIJwELXp6pSwIx1bwpV8Zw92S6G2FpI3OpWEJ",
"CCM_decrypted": {
"card_number": "4111111111111111"
},
"GCM": "YXNkNDU2ZmdoMDEyql2O8UB53Ux94KWoIaIDarnm+6xKaXL2FNfHl5XOCtbv590W5x6ISEI3",
"GCM_decrypted": {
"card_number": "4111111111111111"
}
```
35 changes: 35 additions & 0 deletions integrations/larky/crypto/AES_CCM_GCM/python_sample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import builtins
import json
from requests.auth import HTTPProxyAuth
import base64
from Crypto.Cipher import AES

TAG_LENGTH = 8

session_key = b'vbfhg768ghvbfhg768ghvbfhg768gh12'
nonce = b'asd456fgh012'

body = b'{"card_number":"4111111111111111"}'

cipher_aes = AES.new(session_key, AES.MODE_GCM, nonce=nonce, mac_len=TAG_LENGTH)
ciphertext, tag = cipher_aes.encrypt_and_digest(body)
ciphertext_tag = b"".join([cipher_aes.nonce, ciphertext, tag])
result_GCM = base64.b64encode(ciphertext_tag).decode('utf-8')
print('\n>>> Encrypted GCM: ', result_GCM)

#decrypt GCM:
cipher = AES.new(session_key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)
print("\n>>> GCM decrypted: " + str(plaintext))

cipher_aes = AES.new(session_key, AES.MODE_CCM, nonce=nonce, mac_len=TAG_LENGTH)
ciphertext, tag = cipher_aes.encrypt_and_digest(body)
ciphertext_tag = b"".join([cipher_aes.nonce, ciphertext, tag])
result_CCM = base64.b64encode(ciphertext_tag).decode('utf-8')
print('\n>>> Encrypted CCM: ', result_CCM)

#decrypt CCM:
cipher = AES.new(session_key, AES.MODE_CCM, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)
print("\n>>> CCM decrypted: " + str(plaintext) + '\n')

63 changes: 63 additions & 0 deletions integrations/larky/crypto/AES_CCM_GCM/test_aes_ccm_gcm.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
load("@stdlib//unittest", "unittest")
load("@vendor//asserts", "asserts")
load("@vgs//http/request", "VGSHttpRequest")
load("@stdlib//json", json="json")
load("@stdlib//builtins", builtins="builtins")
load("@vendor//Crypto/Cipher/AES", AES="AES")
load("@stdlib//base64", base64="base64")


def process(input, ctx):
TAG_LENGTH = 8
session_key = b'vbfhg768ghvbfhg768ghvbfhg768gh12'
nonce = b'asd456fgh012'

body_str = str(input.body)
body = json.loads(body_str)

# GCM:
cipher_aes = AES.new(session_key, AES.MODE_GCM, nonce=nonce, mac_len=TAG_LENGTH)
ciphertext, tag = cipher_aes.encrypt_and_digest(builtins.bytes(body_str, 'utf-8'))
ciphertext_tag = b"".join([cipher_aes.nonce, ciphertext, tag])
ciphertext_b64_GCM = base64.b64encode(ciphertext_tag).decode('utf-8')
# decrypt:
cipher = AES.new(session_key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)
body['GCM'] = ciphertext_b64_GCM
body['GCM_decrypted'] = json.loads(str(plaintext))

# CCM:
cipher_aes = AES.new(session_key, AES.MODE_CCM, nonce=nonce, mac_len=TAG_LENGTH)
ciphertext, tag = cipher_aes.encrypt_and_digest(builtins.bytes(body_str, 'utf-8'))
ciphertext_tag = b"".join([cipher_aes.nonce, ciphertext, tag])
ciphertext_b64_CCM = base64.b64encode(ciphertext_tag).decode('utf-8')
# decrypt:
cipher = AES.new(session_key, AES.MODE_CCM, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)
body['CCM'] = ciphertext_b64_CCM
body['CCM_decrypted'] = json.loads(str(plaintext))

body.pop('card_number')
input.body = builtins.bytes(json.dumps(body))
return input


def test_process():
headers = {}
body = b'{"card_number":"4111111111111111"}'
input = VGSHttpRequest("https://test.com", data=body, headers=headers, method='POST')
response = process(input, None)
expected_body = b'{"CCM":"YXNkNDU2ZmdoMDEysNf+zbjlTcFG/q1TPyuLIJwELXp6pSwIx1bwpV8Zw92S6G2FpI3OpWEJ","CCM_decrypted":{"card_number":"4111111111111111"},"GCM":"YXNkNDU2ZmdoMDEyql2O8UB53Ux94KWoIaIDarnm+6xKaXL2FNfHl5XOCtbv590W5x6ISEI3","GCM_decrypted":{"card_number":"4111111111111111"}}'
print(response.body)
print(expected_body)
asserts.assert_that(response.body).is_equal_to(expected_body)


def _testsuite():
_suite = unittest.TestSuite()
_suite.addTest(unittest.FunctionTestCase(test_process))
return _suite

_runner = unittest.TextTestRunner()
_runner.run(_testsuite())

92 changes: 92 additions & 0 deletions integrations/larky/crypto/AES_CCM_GCM/testing-CCM-vs-GCM.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
data:
- attributes:
created_at: '2021-04-26T09:55:37'
destination_override_endpoint: 'https://echo.apps.verygood.systems'
entries:
- classifiers: {}
config:
condition: AND
rules:
- condition: null
expression:
field: PathInfo
operator: matches
type: string
values:
- /post
- condition: null
expression:
field: ContentType
operator: equals
type: string
values:
- application/json
id: 3e4ca047-23e2-4397-9a67-d673cedf4cc8
id_selector: null
operation: REDACT
operations:
- name: github.com/verygoodsecurity/common/compute/larky/http/Process
parameters:
script: |-
load("@stdlib//base64", base64="base64")
load("@stdlib//builtins", builtins="builtins")
load("@stdlib//json", json="json")
load("@stdlib//larky", larky="larky")
load("@vendor//Crypto/Cipher/AES", AES="AES")
load("@vgs//vault", "vault")
def process(input, ctx):
TAG_LENGTH = 8
session_key = b'vbfhg768ghvbfhg768ghvbfhg768gh12'
nonce = b'asd456fgh012'
body_str = str(input.body)
body = json.loads(body_str)
# GCM:
cipher_aes = AES.new(session_key, AES.MODE_GCM, nonce=nonce, mac_len=TAG_LENGTH)
ciphertext, tag = cipher_aes.encrypt_and_digest(builtins.bytes(body_str, 'utf-8'))
ciphertext_tag = b"".join([cipher_aes.nonce, ciphertext, tag])
ciphertext_b64_GCM = base64.b64encode(ciphertext_tag).decode('utf-8')
# decrypt:
cipher = AES.new(session_key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)
body['GCM'] = ciphertext_b64_GCM
body['GCM_decrypted'] = json.loads(str(plaintext))
# CCM:
cipher_aes = AES.new(session_key, AES.MODE_CCM, nonce=nonce, mac_len=TAG_LENGTH)
ciphertext, tag = cipher_aes.encrypt_and_digest(builtins.bytes(body_str, 'utf-8'))
ciphertext_tag = b"".join([cipher_aes.nonce, ciphertext, tag])
ciphertext_b64_CCM = base64.b64encode(ciphertext_tag).decode('utf-8')
# decrypt:
cipher = AES.new(session_key, AES.MODE_CCM, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)
body['CCM'] = ciphertext_b64_CCM
body['CCM_decrypted'] = json.loads(str(plaintext))
body.pop('card_number')
input.body = builtins.bytes(json.dumps(body))
return input
phase: REQUEST
public_token_generator: UUID
targets:
- body
token_manager: PERSISTENT
transformer: JSON_PATH
transformer_config:
- $.email
transformer_config_map: null
host_endpoint: (.*)\.verygoodproxy\.com
id: c891d346-0e1b-49b8-99ac-0754d34f14f2
ordinal: null
port: 80
protocol: http
source_endpoint: '*'
tags:
name: echo.apps.verygood.systems-steel-blue-parallelogram
source: RouteContainer
updated_at: '2021-05-07T11:45:32'
id: c891d346-0e1b-49b8-99ac-0754d34f14f2
type: rule_chain
version: 1
2 changes: 1 addition & 1 deletion integrations/larky/crypto/AES_CTR/inbound-AES-CTR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ data:
encString = base64.urlsafe_b64encode(chipertext).decode()
payload = '&encryptedData=' + encString + '&iv=' + ivv
# final result to be send to dev.finexusgroup.com
# final result to be sent to upstream
enc = bytes(payload, encoding='utf-8')
final = base64.b64encode(enc).decode()
Expand Down

0 comments on commit 8f837ff

Please sign in to comment.