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.
TLS transport security
All Ably client libraries use TLS by default when communicating with Ably over REST or via realtime transports such as WebSockets. This provides a secure transport for communication with Ably, ensuring that messages in transit cannot be intercepted, inspected, or tampered with.
Disabling TLS
If you need to disable TLS (typically to reduce communication overhead for public data streams), you can specify tls: false in your client options when instantiating a Realtime or REST library.
TLS restrictions
Unencrypted communication with Ably is disallowed if any of the following conditions are met:
-
You attempt to use Basic Authentication and thus transmit a private API key over an unencrypted connection. You are only permitted to use unencrypted connections with Token Authentication as tokens expire, limiting the impact of token interception.
-
You have specified that TLS is required in your app settings.
-
A client using an unencrypted connection attempts to attach to a channel that is configured to be used with TLS only.
TLS vs. message encryption
While TLS encryption ensures that messages in transit to and from Ably cannot be intercepted, inspected, or tampered with, it does not ensure that the Ably service itself is unable to inspect your messages and their content. If you want to ensure that all messages are encrypted and inaccessible to even Ably, consider using the message-level encryption feature included in the client libraries.
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.
Cross-platform symmetric encryption
All officially supported Ably client libraries provide cross-platform symmetric encryption, ensuring that encrypted messages can be sent from one platform and successfully decrypted on any other supported platform.
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:
1
2
3
4
5
6
7
8
9
10
const realtime = new Ably.Realtime('demokey:*****');
const cipherKey = await realtime.Crypto.generateRandomKey();
const channel = realtime.channels.get('hay-pot-cam', {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');