Conversation & visitor data encryption¶
Overview¶
Chat conversation, visitor data and visitor file upload encryption is an extra feature in our service. If it is enabled you can toggle encryption for any room in your company.
When encryption is on, whenever a new chat session is created, an AES key is also generated and stored to two places. A plaintext version of the key is stored in cache with a 90-minute expiration time. Another copy of this key is encrypted with customer provided RSA public key and stored to our database.
During chat session this AES key is used to encrypt all message content. Every time a new chat log is saved to database, the cached AES key is given a new expiration time of 90 minutes. While the cached key exist, all chat logs are automatically decrypted.
Visitor API data values are also encrypted. The AES key used in encryption is different from the one used with chat sessions. This key is also cached but only for 30 minutes. The timer resets on every visitor pageload. An RSA encrypted version of this AES key is stored as an API data entry with name _encrypted_aes_key
.
Symmetric AES encryption¶
Our implementation of AES encryption uses https://github.com/pyca/cryptography library maintained by Python Cryptographic Authority (PyCA). We use 256-bit AES keys and encryption is done in CBC mode.
Keys are stored in json
format.
Example of an encryption key
1 2 3 4 5 6 7 8 9 |
|
Encrypted data is also signed with a HMAC key. The ciphertext resulting from encryption has following format:
- First 5 bytes are metadata
- Next 16 bytes are the initialization vector
- Next bytes are the encrypted content
- Last 20 bytes are the signature, which is generated over all the preceding bytes
Please note that the signature is generated over already encrypted data. Before storing the ciphertext it is base64 encoded.
Asymmetric RSA encryption¶
After generating the AES key it is encrypted with customer's RSA public key and stored. Our implementation uses PyCryptodome's RSA module. RSA key has to be at least 2048-bits long. RSA encryption follows PKCS #1 OAEP standard
How to generate keys?¶
To generate RSA key pair you can use following openssl commands.
How to generate keys with OpenSSL
1 2 |
|
These will generate you a RSA key pair and save them to files private.pem
and public.pem
. Public key from public.pem
can be pasted to our public key settings interface as is.
How to decrypt?¶
While the AES key exists in our cache chat logs are decrypted automatically. After that decryption has to be done by customer.
Giosg provides multiple ways to decrypt your data. Easiest way is to use Giosg Vault Decrypt app. This app is a web interface where you can paste your private key and get the decrypted chat data back. However this app is not meant for bulk decryption and is useful only if you need to occasionally decrypt chat logs.
For more advanced use cases where you want to automate decryption you can use our Giosg Crypter Python package. This package provides a command line tool and a Python library to decrypt your data.
Giosg also provides similar tool written in Java as an example if you need to implement decryption in Java or some other language to integrate to your stack.
Decryption using Giosg Crypter¶
Install Giosg Crypter Python package and follow the guide it provides. Familiarity with Python and our HTTP API and Public HTTP API documentations are recommended.
First install the required dependencies and either use the installed command line tool or create your own script with the Python library.
Installing dependencies
1 |
|
Command line tool
1 |
|
Create your own script
1 2 3 4 5 6 7 8 9 |
|
Implementing your own decryption¶
In case you want or need to implement your own decryption app, here are the steps you should performn. Input data and expected outputs to test that functionality is correct can be found from below.
Steps¶
- Load RSA Private key from PEM file
- Load chat session and its messages from Giosg Chat's API and Chat Messages API's.
- Read
encrypted_symmetric_key
field from the chat session. This is the AES key encrypted with customer's RSA public key. base64
decode the bytes ofencrypted_symmetric_key
.- Use RSA private key to decrypt the
encrypted_symmetric_key
. It uses PKCS#1 OAEP protocol with SHA-1. - Parse the the decrypted value of
encrypted_symmteric_key
as JSON and get the valueaesKeyString
from the parsed JSON. - URL Safe base64 decode the
aesKeyString
value. - Loop over the chat messages in the session and use AES key
aesKeyString
to decrypt the message content from fieldencrypted_message
. UseAES/CBC/PKCS5Padding
mode.
You may also take a look on our open source Github repositories https://github.com/giosg/giosg_crypter/ and https://github.com/giosg/java-decrypt-app to see how it is implemented in Python and Java.
Example input¶
If you implement your own decryption you can use these keys and inputs to verify that the your decryption code works
Decryption process:
- Use RSA Private Key (example data 1) to decrypt RSA encrypted AES key (example data 2)
- If the encryption was successful then the result should be Decrypted AES Key (example data 3)
- Use Decrypted AES Key (example data 3) to decrypt the AES encrypted message content (example data 4)
- If the encryption was successful then the result should be AES decrypted message content (example data 5)
Example data 1: Example RSA private key (do not use in production)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Example data 2: RSA encrypted AES key
1 2 3 4 5 |
|
Example data 3: Output RSA decrypted AES key
1 2 3 4 5 6 7 8 9 |
|
Example data 4: AES encrypted message content
1 2 |
|
Example data 5: AES decrypted message content
1 |
|