Secure channel encryption
Updated
Add Agora built-in media stream encryption to your app.
Media stream encryption ensures that only authorized users in a channel see and hear each other. 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, when required.
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 a salt to encrypt and decrypt data in the channel. You use the key and salt to create an encryption configuration. Agora SDRTN® uses the encryption configuration to encrypt a stream and sends it to remote users. When a remote user receives an encrypted media stream, the remote app decrypts it using the same salt and key.
The following figure shows the call flow for media stream encryption:
All users in a channel must use the same encryption configuration. You set this up when you initiate the Agora Engine and enable encryption before joining a channel. If you don’t have the correct configuration, you cannot decrypt channel content. Best practice is to have your authentication system generate a new key and salt regularly.
IoT SDK supports the following encryption modes:
- SM4-128-ECB
- AES_128_ECB
- AES_128_XTS
- AES_256_XTS
- AES-128-GCM
- AES-256-GCM
- AES-128-GCM2 (recommended)
- AES-256-GCM2 (recommended)
Compared to other encryption modes, GCM2 encryption uses a more secure key derivation function and supports salt. If you choose another encryption mode, you only need to set the encryption mode and key.
Prerequisites
To follow this procedure you must have:
-
Implemented the SDK quickstart project for IoT SDK.
-
OpenSSL v3.0.0 or above.
Project setup
To encrypt media streams in your app, you need to:
-
Open the SDK quickstart IoT SDK project you created previously.
-
Set up OpenSSL on your development device.
Implement Agora media stream encryption
To implement media stream encryption, do the following:
-
Add variables to hold the encryption mode, encryption key, and salt
Open
<project-root>/agora_rtsa_sdk/example/hello_rtsa/hello_rtsa.cin your development environment and add the following declarations tomain()afterchar params[512];:char * encryptionMode; // depends on your choice of an encryption method const char * encryptionKey = "<32-byte key generated through OpenSSL>"; const char * encryptionSaltBase64 = "<Base64-encoded, salt generated through OpenSSL>"; -
Enable encryption
Set
enable_aut_encryptiontotruein the channel options. Add the following line inmain()afterchannel_options.auto_subscribe_video = true:channel_options.enable_aut_encryption = true; -
Set encryption parameters
You specify the media stream encryption mode and the related parameters in JSON format by calling
agora_rtc_set_params. Depending on your choice of an encryption mode, add one of the following pieces of code beforeagora_rtc_join_channelfunction inmain():-
SM4-128-ECB encryption
// set the encryption mode encryptionMode = "SM4-128-ECB"; // set encryption parameters memset(params, '\0', sizeof(params)); snprintf(params, sizeof(params), "{\"rtc.encryption\": {\"enable\": true,\"mode\": \"%s\", \"master_key\": \"%s\" }}", encryptionMode, encryptionKey); rval = agora_rtc_set_params(params); if (rval != 0) { LOGE("set encryption key failed, reason: %s", agora_rtc_err_2_str(rval)); return -1; } -
AES-128-GCM encryption
// set the encryption mode encryptionMode = "AES-128-GCM"; // set encryption parameters memset(params, '\0', sizeof(params)); snprintf(params, sizeof(params), "{\"rtc.encryption\": {\"enable\": true,\"mode\": \"%s\", \"master_key\": \"%s\" }}", encryptionMode, encryptionKey); rval = agora_rtc_set_params(params); if (rval != 0) { LOGE("set encryption key failed, reason: %s", agora_rtc_err_2_str(rval)); return -1; } -
AES-128-GCM2 encryption
// set the encryption mode encryptionMode = "AES-128-GCM2"; // set encryption parameters memset(params, '\0', sizeof(params)); snprintf(params, sizeof(params), "{\"rtc.encryption\": {\"enable\": true,\"mode\": \"%s\", \"master_key\": \"%s\", \"salt_type\": \"BASE64\"}}" }}", encryptionMode, encryptionKey, encryptionSaltBase64); rval = agora_rtc_set_params(params); if (rval != 0) { LOGE("set encryption key failed, reason: %s", agora_rtc_err_2_str(rval)); return -1; }
-
-
Disable encryption
To disable encryption, use the following code:
// Disable built-in encryption agora_rtc_set_params("{\"rtc.encryption\": {\"enable\": false}}");
Test your implementation
To ensure that you have implemented Agora media stream encryption in your app:
-
Add the 32-byte key to your app:
-
Run the following command in a terminal window:
openssl rand -hex 32 -
Paste the key string returned into the
encryptionKeyvariable.
-
-
Add the 64-byte salt to your app:
-
Run the following command in your terminal window:
openssl rand -base64 32 -
Paste the salt string returned into the
encryptionSaltBase64variable.
-
-
Generate a temporary token in Agora Console.
-
Compile the sample project by executing the following commands in a terminal window:
cd <project-root>/agora_rtsa_sdk/example ./build-x86_64.sh -
Run the sample app by executing the following commands:
cd out/x86_64 ./hello_rtsa --app-id <your-app-id> --channel-id <your-channel-name> --token <authentication-token>Make sure you insert your app ID, channel ID, and token from Agora Console in to the command.
On launch, the app joins a channel and shows output similar to the following:
[INF] Welcome to RTSA SDK v1.9.0 [INF] File parser found: h264 [INF] File parser found: pcm [INF] [conn-1] Join the channel demo successfully, uid 2645490531 elapsed 602 ms [INF] [conn-1] Bandwidth change detected. Please adjust encoder bitrate to 499 kbps -
Test with an unauthorized user
In your browser, navigate to the Agora web demo and update App ID, Channel, and Token with the values for your temporary token, then click Join. You see the local user video in your browser.
In the terminal, your compiled app shows a decryption error as the web demo does not have the SSL key and salt for stream encryption and decryption.
[INF] [conn-1] Remote user "3674330576" has joined the channel, elapsed 6784 ms [WRN] Error 120 is captured. Error msg "audio:decrypt error" [WRN] Error 120 is captured. Error msg "video:not set" -
Test with an authorized user
Open two Linux terminals. Navigate to
<project-root>/agora_rtsa_sdk/example/out/x86_64and execute the following command to launch the app from both terminals../hello_rtsa --app-id <your-app-id> --channel-id <your-channel-name> --token <authentication-token>You see that both clients join the same channel and successfully exchange data as they are using the same SSL key and salt.
Terminal output for User 1:
[DBG] [conn-1] on_audio_data, uid 3534962825 sent_ts 28149 data_type 100, len 640 [DBG] [conn-1] on_video_data: uid 3534962825 sent_ts 28150 data_type 2 frame_type 4 stream_type 0 len 618 [DBG] [conn-1] on_audio_data, uid 3534962825 sent_ts 28169 data_type 100, len 640Terminal output for User 2:
[DBG] [conn-1] on_video_data: uid 2689257578 sent_ts 1494 data_type 2 frame_type 4 stream_type 0 len 160 [DBG] [conn-1] on_video_data: uid 2689257578 sent_ts 1534 data_type 2 frame_type 4 stream_type 0 len 189 [DBG] [conn-1] on_audio_data, uid 2689257578 sent_ts 1541 data_type 100, len 640
Communication between your test devices is now end-to-end encrypted. This prevents data from being read or secretly modified by anyone other than the true sender and recipient.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
