Can I pass secure values into Malcolm! Workflows via the URL?

Passing data into a Workflow via the URL is a feature we've had for a while - read more.

But what if the data you want to pass is confidential?

Understandably, you wouldn't want to pass that straight in. Luckily Malcolm! understands how important protecting your data is so we've come up with a solution that allows values to travel safe and secure with minimal effort!

A beginners guide to encryption

Suppose you have a value, such as an account number, that you don't want anyone else to read. Encryption provides a way to scramble this value so only you and the people you share the password or secret key with can read it.

encryption-diagram.png

The sender uses the secret key to scramble the original value and the encrypted value is sent to the receiver. On receipt of the encrypted value the receiver uses the same secret key to unscramble the value back to the original.

And that's encryption in a nutshell!

Step 1: Generate a secret key

The secret key can be any string you like, but Malcolm! recommends using a random string of at least 36 characters. A simple ruby command can quickly generate one for you.

ruby -rsecurerandom -e 'puts SecureRandom.hex(18)'

Keep your secret key safe - you'll need it later!

Step 2: Share your secret key with Malcolm!

We do this via the Workflow Builder. Any question field that supports URL query values can now be secured with your secret key - e.g. text fields, hidden fields, number fields, email address fields, etc.

Screenshot 2021-11-10 at 13.43.37.png

Here's a simple example which starts with a text field renamed to "Account number".

Screenshot 2021-11-10 at 13.51.53.png

To enable URL values open up the edit window, scroll to the bottom and turn on "Allow a value to be set in URL query". Malcolm! will automatically generate a query name for you but you can change it to something different if you prefer.

Screenshot 2021-11-10 at 13.52.01.png

Nex turn on the "Secure the query value" and paste in your secret key. In our example below we're using "xxxxxx" for simplicity but yours should be a lot longer!

Hit save and that completes the configuration!

Step 3: Encrypting values

Malcolm! uses OpenSSL and the "aes-128-gcm" cipher to decrypt values.

Passed values need to be encoded and made up of three parts -

  1. The Initialisation Vector used during the encryption
  2. The Authentication Tag resulting from AEAD ciphers
  3. The encrypted string

Initialisation Vectors are generated using the OpenSSL rand function. For our chosen cipher these need to be exactly 12 bytes long. If using PHP you can use the openssl_random_pseudo_bytes function.

$iv = openssl_random_pseudo_bytes(12);

Why 12 bytes? This just happens to be the required length for our chosen cipher. In PHP you can verify this by using the openssl_cipher_iv_length function.

echo openssl_cipher_iv_length('aes-128-gcm');

This will output -

12

Next use the OpenSSL enc function to create the encrypted string. Here's an example using the PHP openssl_encrypt function.

$plaintext = 'The text you would like to encrypt';

$cipher = 'aes-128-gcm';

$key = 'xxxxxx';

$iv = openssl_random_pseudo_bytes(12);

$ciphertext = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);

This will assign an Authentication Tag to the $tag variable (passed by reference) and an encrypted string to the $ciphertext variable.

Note - in PHP we pass OPENSSL_RAW_DATA to generate binary data.

Complete the process by concatenating $iv, $tag and $cipertext into a single string - Malcolm! needs all three for the decryption process!

$rawstring = $iv . $tag . $ciphertext;

As we're passing this value via the URL we need to first encode it. Use a Base 64 encoder followed by a URL encoder to ensure all the characters are sent correctly. In PHP this is the base64_encode function and urlencode functions respectively.

$encodedstring = urlencode(base64_encode($rawstring));

This is the final encoded string!

$url = '/workflows/encryption-test?account-number=' . $encodedstring;

For simplicity all the steps from above can be put in a single function.

/**
 * Create a secure a value for a URL query.
 *
 * @param  string  $plaintext
 * @param  string  $key
 * @return string
 */
function secure_url_value($plaintext, $key) {

    $iv = openssl_random_pseudo_bytes(12);

    $ciphertext = openssl_encrypt($plaintext, 'aes-128-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);

    $rawtext = $iv . $tag . $ciphertext;

    $encodedtext = urlencode(base64_encode($rawtext));

    return $encodedtext;
}

And that's all there is to it ;)

Upgrade your content

Want to give your users a graphical run-down of how your products or services work? Malcolm! Agency Services can help

Learn more

Hey there!

Malcolm! is brought to you by a passionate and dedicated team - we love all things customer support related! Find out more about us here

Find out more