Encryption Keys
To try it out today, email us at [email protected]
Working with encryption keys
This page demonstrates how to use public/private keys in Larky code, store them in your vault, and prepare the client app for their usage.
Larky code sample
There is an example of code below, which:
Reads the private/public key aliases from the input headers. If the header is absent, use a hardcoded value. The key aliases have to be redacted prior to using this code; see the Preparing encryption keys paragraph below.
Reveals the key aliases on the fly.
Imports the public key and encrypts the test message.
Imports the private key and decrypts the result of the encryption above.
It is recommended against storing any sensitive data in the route configuration (YAML). Instead, the keys should be stored in the vault, while the route can contain their aliases. Alternatively, the key aliases can be supplied by the client application, for example, in the headers as it's shown in the example below.
load("@stdlib//base64", base64="base64")
load("@stdlib//json", json="json")
load("@stdlib//larky", larky="larky")
load("@stdlib//builtins", builtins="builtins")
load("@vgs//vault", "vault")
load("@vendor//Crypto/Cipher/PKCS1_OAEP", PKCS1_OAEP="PKCS1_OAEP")
load("@vendor//Crypto/PublicKey/RSA", RSA="RSA")
def process(input, ctx):
# reading body
body = json.loads(str(input.body))
# reading headers
headers = input.headers
# careful reading:
# if header is absent - use hardcoded alias
# if header exists - read it and delete
private_key = 'tok_sandbox_wptPRsWr2N5hyXGvkZ8247'
if 'private' in headers:
private_key = headers.pop('private')
public_key = 'tok_sandbox_8uLH3XdekgzSYa2mpiRwwi'
if 'public' in headers:
public_key = headers.pop('public')
# reveal of keys
private_key = vault.reveal(private_key)
public_key = vault.reveal(public_key)
## Encryption part:
message = bytes(body['message'], 'utf-8')
# importing public key
key = RSA.importKey(base64.b64decode(public_key))
# encrypt
cipher = PKCS1_OAEP.new(key)
ciphertext = cipher.encrypt(message)
# writing result into the body
body['message_encrypted'] = base64.b64encode(ciphertext).decode('utf-8')
## Decryption part:
body_utf8 = base64.b64decode(bytes(body['message_encrypted'], 'utf-8'))
# importing private key
key = RSA.importKey(base64.b64decode(private_key))
# decrypt
cipher = PKCS1_OAEP.new(key)
message = cipher.decrypt(body_utf8)
# writing result into the body
body['message_decrypted'] = str(message)
input.body = builtins.bytes(json.dumps(body))
input.headers = headers
return input
Testing (with headers)
Request to send:
curl {VAULT_URL}/post \
-H 'Content-Type: application/json' \
-H 'Private: tok_sandbox_wptPRsWr2N5hyXGvkZ8247' \
-H 'Public: tok_sandbox_8uLH3XdekgzSYa2mpiRwwi' \
-d '{
"message": "The force will be with you!"
}'
Response example:
{
"message": "The force will be with you!",
"message_decrypted": "The force will be with you!",
"message_encrypted": "C4opqcXPweJsqXW+CSGFUUC+xeSyLjY7CxMAZlsMHHrtEA3wp5dg0yMIua+LNTk4w25wUuJVX1taOACM9A3D3mIZO9m8JXgEogoryvPbaMk8e3SxdxdXzrMFvTS0IO00n8Vh4vs6YoyZ6unsH/4IxGM8WrEsO6LVYwSSgx7Hwlk2tizcxOhUWclFFfXX+jyHwxmXsWD0mU8UZotj+mZTXCuA1o9vCw3lJCEP51WqDw0Hi0aa5En1Ym4o7IBvH76gABis30fS0vl97CwVQqC5tcH5nvHxd93XBtut7vwr5JxG95beracmEOZVQ/NvmJf0fScx6++IbnLldCUFEqVIZA=="
}
Testing (without headers)
Request to send:
curl {VAULT_URL}/post \
-H 'Content-Type: application/json' \
-d '{
"message": "The force will be with you!"
}'
Response example:
{
"message": "The force will be with you!",
"message_decrypted": "The force will be with you!",
"message_encrypted": "MILS9RYt3+oWcEyS/IMfmEfhPSBOTUwjUxcDYyJflxnIL+qElnINZaY9VWX/RzIDqEuax8BEkbxtDeXRSFNrXwYj++B3n7dXAGbLXrYXnhRcsnYzgNYDsIGPYYQJZe/Vm7ewq4p7OfdMm0zA8DhoWA5Z6KQOu97SNNtQ8FppVzKofBnHZdJeDpjPKOUIQ70QDzF5M55YistzKXBQCgxZofTR+jaX/p/JHih/I9amQK9hQ3nOlHE3ilH65TMRG2MghIp60nMMWhKo7Se7AGu6Ur4A8v0TMrjs0MkMWYMAMUHOnkqL+Iy64eS9qiEFrEwwos0Vs36Ij+YRO028KvaV6A=="
}
Preparing encryption keys
Create a pair of keys (public/private) using any convenient approach.
Take the content of each key without the beginning
-----BEGIN PUBLIC KEY-----
and the ending-----END PUBLIC KEY-----
Remove linebreaks (i.e., make the key as one line)
Create an Inbound Route with a default filter and operation to redact two JSON fields:
$.public
and$.private
Redact the keys:
curl {VAULT_URL}/post \
-H 'Content-Type: application/json' \
-d '{
"private": "MIIEpAIBAAKC**********************P0Z27CL5Cg==",
"public": "MIIBIjANBgkqhkiG9*******************wxwwIDAQAB"
}'
Grab the aliases from the response (see below) and paste them either in Larky code or in the client application to send in headers (or both places):
{
"private": "tok_sandbox_wptPRsWr2N5hyXGvkZ8247",
"public": "tok_sandbox_8uLH3XdekgzSYa2mpiRwwi"
}
Useful links
Last updated