Skip to main content
Android
iOS
macOS
Web
Windows
Electron
Flutter
React Native
React JS
Unity
Unreal Engine
Unreal (Blueprint)

Secure channel encryption

Media stream encryption refers to encrypting audio and video streams in an app using a unique key and salt controlled by the app developer. Encryption ensures that only the authorized users in a channel see and hear each other. Video SDK provides built-in encryption methods that you can use to guarantee data confidentiality during transmission.

This article describes how to integrate Agora built-in media stream encryption into your app.

Understand the tech

The following figure illustrates the process of data transfer with media stream encryption enabled.

Best practice is to choose the AES_128_GCM2 or AES_256_GCM2 encryption mode and set a key and salt for enhanced security.

EncryptMediaStream

Prerequisites

Ensure that you have implemented the SDK quickstart in your project.

Implement media stream encryption

To add built-in media stream encryption to your app, refer to the following steps:

  1. Generate a key and salt on your server

    • To generate a random 32-byte hexadecimal key on your server as a string, refer to the following OpenSSL command:

      # Generate a 32-byte hexadecimal key
      openssl rand -hex 32
      Copy
    • To generate a random Base64-encoded, 32-byte salt on your server, refer to the following OpenSSL command:

      # Generate a Base64-encoded, 32-byte salt
      openssl rand -base64 32
      Copy
  1. Implement client-side logic

    1. Get the String key and Base64-encoded salt from the server.

    2. Convert salt from Base64 to uint8_t.

    3. Before joining the channel, call enableEncryption to set the AES_128_GCM2 or AES_256_GCM2 encryption mode, and pass the key and salt to the SDK.

    note
    • All users in a channel must use the same encryption mode, key, and salt. Discrepancies may lead to unexpected behavior, such as black screens or audio loss.
    • To ensure security, best practice is to use a new key and salt each time you enable media stream encryption.

    To implement this logic, refer to the following code:

    #include <boost/algorithm/string/trim.hpp>
    #include <boost/archive/iterators/base64_from_binary.hpp>
    #include <boost/archive/iterators/binary_from_base64.hpp>
    #include <boost/archive/iterators/transform_width.hpp>
    #include <boost/range/algorithm/copy.hpp>

    namespace detail {
    using Base64FromBinary = boost::archive::iterators::base64_from_binary<
    boost::archive::iterators::transform_width<const char*, 6, 8>>;

    using BinaryFromBase64 = boost::archive::iterators::transform_width<
    boost::archive::iterators::binary_from_base64<std::string::const_iterator>,
    8, 6>;
    }

    void decodeBase64(const std::string& encoded, std::vector<uint8_t>& out) {
    auto unpadded = encoded;

    const auto num_padded = std::count(begin(encoded), end(encoded), '=');
    std::replace(begin(unpadded), end(unpadded), '=', 'A'); // A_64 == \0

    std::string decoded{
    detail::BinaryFromBase64{begin(unpadded)},
    detail::BinaryFromBase64{begin(unpadded) + unpadded.length()}};

    decoded.erase(end(decoded) - num_padded, end(decoded));
    std::copy(begin(decoded), end(decoded), out.begin());
    }

    // Initialize the rtcEngine before calling this method
    int enableEncryption() {
    std::string secret;
    std::string kdfSaltBase64;
    std::vector<uint8_t> kdfSalt;
    for (int i = 0; i < 32; ++i) {
    kdfSalt.push_back(0);
    }
    if (!getSecretAndSaltFromSever(secret, kdfSaltBase64)) return -1;
    if (rtcEngine && decodeBase64(kdfSaltBase64, kdfSalt)) {
    // Create an instance of EncryptionConfig
    agora::rtc::EncryptionConfig config;
    // Set the encryption mode to AES_128_GCM2
    config.encryptionMode = AES_128_GCM2;
    // Set the encryption key
    config.encryptionKey = secret.c_str();
    // Set the sault
    memcpy(config.encryptionKdfSalt, kdfSalt.data(),
    sizeof(config.encryptionKdfSalt));
    // Turn on built-in encryption
    return rtcEngine->enableEncryption(true, config);
    }
    return -1;
    }
    Copy

    The sample code utilizes Boost, a third-party library, which you can download here.

Information
To communicate with the Video SDK for Web, convert the String type key mentioned in this document from Hex encoding format to the ASCII encoding format.

Reference

This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.

Sample projects

Agora provides open-source sample projects for your reference. Download or view the source code for a more detailed example.

API reference

vundefined