# Secure channel encryption (/en/realtime-media/interactive-live-streaming/build/secure-and-protect-channels/media-stream-encryption/web)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

Media stream encryption encrypts audio and video streams with a unique [key](https://en.wikipedia.org/wiki/Public_key_certificate) and [salt](https://en.wikipedia.org/wiki/Salt_\(cryptography\)) controlled by your app server. Encryption ensures that only authorized users in a channel can see and hear each other.

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

    ## Understand the tech [#understand-the-tech-3]

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

    **Data transfer process**

    ![Encrypted media stream transfer process for Web](https://assets-docs.agora.io/images/video-sdk/encrypt_media_streams_dataTransferProcess-web.svg)

    ## Prerequisites [#prerequisites-3]

    Ensure that you have implemented the [SDK quickstart](../../index.mdx) in your project.

    ## Implement media stream encryption [#implement-media-stream-encryption-3]

    Video SDK for Web supports the following encryption modes:

    * `"aes-128-xts"`: 128-bit AES encryption, XTS mode.
    * `"aes-256-xts"`: 256-bit AES encryption, XTS mode.
    * `"aes-128-gcm"`: 128-bit AES encryption, GCM mode.
    * `"aes-256-gcm"`: 256-bit AES encryption, GCM mode.
    * `"aes-128-ecb"`: 128-bit AES encryption, ECB mode.
    * `"sm4-128-ecb"`: 128-bit SM4 encryption, ECB mode.

    Available only in Web SDK v4.5.0 and higher:

    * `"aes-128-gcm2"`: 128-bit AES encryption, GCM mode, salted.
    * `"aes-256-gcm2"`: 256-bit AES encryption, GCM mode, salted.

    For maximum security, set the encryption mode to `"aes-128-gcm2"` or `"aes-256-gcm2"` and specify an encryption key and salt. If you choose another encryption mode, you only need to specify the encryption key.

    1. Generate a key and salt on your server.

       ```bash
       openssl rand -hex 32
       ```

       ```bash
       openssl rand -base64 32
       ```

    2. Before joining a channel, call `AgoraRTCClient.setEncryptionConfig` to select the encryption mode and specify the encryption key and salt.

       ```typescript
       function base64ToUint8Array(base64Str: string): Uint8Array {
         const raw = window.atob(base64Str);
         const result = new Uint8Array(new ArrayBuffer(raw.length));

         for (let i = 0; i < raw.length; i += 1) {
           result[i] = raw.charCodeAt(i);
         }

         return result;
       }

       function hexToAscii(hexValue: string) {
         let result = '';
         for (let i = 0; i < hexValue.length; i += 2) {
           result += String.fromCharCode(parseInt(hexValue.slice(i, i + 2), 16));
         }
         return result;
       }

       const [secretFromServer, saltFromServer] = await getSecretAndSaltFromServer();
       const secret = hexToAscii(secretFromServer);
       const salt = base64ToUint8Array(saltFromServer);

       client.setEncryptionConfig('aes-256-gcm2', secret, salt);
       ```

    <CalloutContainer type="info">
      <CalloutDescription>
        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, use a new key and salt each time you enable media stream encryption.
      </CalloutDescription>
    </CalloutContainer>

    ## Reference [#reference-3]

    ### Development considerations [#development-considerations]

    The media stream encryption feature is supported in both communication and live broadcasting use cases. However, Agora does not support pushing encrypted media streams to CDN.

    ### API reference [#api-reference-3]

    * [`setEncryptionConfig`](https://api-ref.agora.io/en/video-sdk/web/4.x/interfaces/iagorartcclient.html#setencryptionconfig)
    * [`EncryptionMode`](https://api-ref.agora.io/en/video-sdk/web/4.x/globals.html#encryptionmode)

    
  
      
  
      
  
      
  
      
  
      
  
