Encryption
Transport Layer Security (TLS) is enabled by default in Ably SDKs so that data is securely sent to, and received from, Ably. However, messages are not encrypted within the Ably system. Use the encryption channel option to ensure that message payloads are opaque, that they can’t be decrypted by Ably, and can only be decrypted by other clients that share your secret key.
Setting encryption using channel options means that encryption is a feature that can be set per-channel. Apps may have both un-encrypted and encrypted channels on a single connection.
Encryption with Ably
Ably SDKs support encryption purely as a convenience. The SDKs ensure interoperability between environments by having compatible implementations of encryption algorithms and by making common choices on things such as format, mode and padding. However, Ably intentionally does not manage the distribution of keys between clients, and end-to-end encryption is enabled without exposing keys to the Ably service at all. This has the advantage that Ably has no access to the un-encrypted contents of your messages, but also means that each app is responsible for enabling the distribution of keys to clients independently of Ably.
Encryption with Ably supports symmetric encryption only and requires each participating client to each specify the correct CipherParams
secret key
when creating a channel
instance. Clients that do not specify a key will receive the still-encrypted message payloads, that they can subsequently decrypt offline if necessary.
Only the AES algorithm, with a default key length of 256 bits, and CBC mode are supported. These defaults are intended to ensure that encryption support can be provided in all target environments and platforms.
Encryption is supported for the data
attribute, or payload, of published messages and presence messages on a channel, using both the REST and realtime interfaces. Decryption is supported for message and presence message subscriptions in the realtime interface, and for both the REST and realtime interfaces when using history.
Other attributes of messages and presence messages, such as event name
and clientId
remain un-encrypted. This means that all sensitive data should be placed in the data
attribute to ensure it is encrypted before it is transmitted to Ably.
The key that’s in use at any given time is known by the SDK. The Ably service only knows that a given message payload was encrypted, not the key used to encrypt it. When accessing messages using the history feature, it is the caller’s responsibility to ensure that the correct key is configured for the channel before the history request is made.
Encrypt a channel
Set the cipher
property to enable message encryption by passing a CipherParams
object that contains at least a secret key
.
A key
should be a cryptographic key generated from a secure random source, 128 or 256 bits long and binary or base-64 encoded. Ably SDKs are also capable of generating a random key. If you wish to encrypt messages with a pass-phrase, for example one entered by a user then use a key derivation function to transform that into a key.
The following is an example of setting encryption when obtaining a channel instance:
const realtime = new Ably.Realtime('<loading API key, please wait>');
const cipherKey = await realtime.Crypto.generateRandomKey();
const channel = realtime.channels.get('gas-cam-oar', {cipher: {key: cipherKey}});
await channel.subscribe((message) => {
console.log(message.name) //unencrypted
console.log(message.data) //encrypted
});
await channel.publish('unencrypted-name', 'data is encrypted');
Demo OnlyCopyCopied!
If you are using Python 2 and you wish to pass in a base64-encoded key, make sure you pass it in as a unicode
string, not a str
, or the library will interpret it as a binary.