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

  1. Create a pair of keys (public/private) using any convenient approach.

  2. Take the content of each key without the beginning -----BEGIN PUBLIC KEY----- and the ending -----END PUBLIC KEY-----

  3. Remove linebreaks (i.e., make the key as one line)

  4. Create an Inbound Route with a default filter and operation to redact two JSON fields: $.public and $.private

  5. Redact the keys:

curl {VAULT_URL}/post \
  -H 'Content-Type: application/json' \
  -d '{
    "private": "MIIEpAIBAAKC**********************P0Z27CL5Cg==",
    "public": "MIIBIjANBgkqhkiG9*******************wxwwIDAQAB"
    }'
  1. 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"
}

Last updated