Secure channel encryption

Updated

Add Agora built-in media stream encryption to your app.

Media stream encryption prevents potential eavesdroppers from accessing sensitive and private information shared in a channel. IoT SDK provides built-in encryption methods that you can use to guarantee data confidentiality during transmission.

This page shows you how to integrate media stream encryption into your app using IoT SDK.

Understand the tech

To ensure secure communication, your app uses an SSL key and, for some encryption modes, a salt to encrypt and decrypt data in the channel. Agora SDRTN® uses your key and salt to encrypt a stream and sends it to remote users. When a remote user receives an encrypted media stream, their app decrypts it using the same key and salt.

The following figure shows the call flow for media stream encryption:

All users in a channel must use the same encryption mode, key, and salt. You set this configuration before you join a channel.

Mismatched encryption configurations between users cause undefined behavior, such as a black screen or lost audio, instead of an explicit error. Best practice is to have your authentication system generate a new key and salt regularly.

IoT SDK supports the following encryption modes:

  • AES_128_XTS
  • AES_128_ECB
  • AES_256_XTS
  • SM4_128_ECB
  • AES_128_GCM
  • AES_256_GCM
  • AES_128_GCM2 (recommended)
  • AES_256_GCM2 (recommended)

AES_128_GCM2 and AES_256_GCM2 use a more secure key derivation function and support a salt. For the other modes, you only need to set the encryption mode and key.

Prerequisites

To follow this procedure you must have:

Generate a key and salt

Generate a 16-byte encryption key:

openssl rand -hex 16

If you use AES_128_GCM2 or AES_256_GCM2, also generate a Base64-encoded, 32-byte salt:

openssl rand -base64 32

Enable encryption

Set the crypto_opt fields of rtc_channel_options_t before you call agora_rtc_join_channel:

rtc_channel_options_t channel_options = { 0 };

// Enable encryption
channel_options.crypto_opt.enable = true;
// Set the encryption mode
channel_options.crypto_opt.mode = AES_128_GCM2;
// Set the key
sprintf(channel_options.crypto_opt.key, "%s", key_str);

// Set the salt (AES_128_GCM2 and AES_256_GCM2 only)
uint8_t *salt_bytes = NULL;
uint32_t salt_bytes_len = 0;
salt_bytes = util_base64_decode(salt_base64_str, strlen(salt_base64_str), &salt_bytes_len);
memcpy(channel_options.crypto_opt.salt, salt_bytes, salt_bytes_len);
free(salt_bytes);

// Join the channel
agora_rtc_join_channel(conn_id, channel_name, uid, token, &channel_options);

key_str and salt_base64_str are the key and salt you generated in Generate a key and salt. If your encryption mode doesn't use a salt, omit the salt-related lines.

Reference