跳到主要内容

自定义加密

在实时音视频互动中,开发者可选择对媒体流进行加密,从而保障用户的数据安全。融云提供两套加密方案:

  1. SDK 内置 SRTP 安全实时传输协议,即协议层的标准加密方式。以开关形式提供,使用简单。
  2. 开发者对媒体数据的自定义加密。即加解密完全由开发者实现,融云服务只对数据做转发,适用于对安全性有特殊要求的客户。此类加密方式,服务端无法做合流处理,所以不适用于直播。
  3. 使用自定义加密后,无法使用部分 RTC 服务端功能,包括:云端录制云端截图内容审核云播放器
提示
  • 若使用自定义加密,需要确保发送端和接收端的加解密算法一致,否则会无法正常通话。
  • 自定义加密,可分别针对音频或视频的原始数据执行,音频和视频的加密算法可以独立设置,或对其中之一进行设置。
  • 由于数据量大,考虑性能原因,自定义的加密算法需要在 C++ 层实现。 注意

无论何种加密方式,都会对客户端、服务器造成额外的资源消耗,在低性能设备上可能会影响体验。

SRTP 加密

初始化 RTC SDK 时,在 Config 中打开 SRTP 开关即可。

  • 示例代码:

    Builder config = Builder.create();
    config.enableSRTP(true);
    RCRTCEngine.getInstance().init(getApplicationContext(), config.build());

自定义加密

步骤 1:开启自定义加密

RCRTCConfig config = Builder.create()
//开启自定义音频加解密
.enableAudioEncryption(true)
// 开启自定义视频加解密
.enableVideoEncryption(true)
.build();
RCRTCEngine.getInstance().init(getApplicationContext(), config);

在 5.3.0 及以后的版本中,您需要通过 RCRTCRoomConfig 开启自定义加密。

RCRTCRoomConfig.Builder builder = RCRTCRoomConfig.Builder.create()
.enableAudioEncryption(true)
.enableVideoEncryption(true);
RCRTCEngine.getInstance().joinRoom("roomId", builder.build(), new IRCRTCResultDataCallback<RCRTCRoom>() {
@Override
public void onSuccess(RCRTCRoom data) {

}

@Override
public void onFailed(RTCErrorCode errorCode) {

}
});

步骤 2:配置 NDK 环境

如果开发者的 Android App 项目还没有使用过 C++,请参考 知识库文档 配置 NDK 编译。

步骤 3:加载自定义加密 so

// so 库名称可根据自己项目来自定义
System.loadLibrary("custom_frame_crypto");

步骤 4:实现加解密逻辑

音频加解密,需要在 C++ 层实现 CustomAudioFrameEncryptor 和 CustomAudioFrameDecryptor 类:

  • 音频加密示例代码:

    /**
    自定义加密方法
    @param payload_data 加密前的数据起始地址
    @param payload_size 加密前的数据大小
    @param encrypted_frame 加密后的数据起始地址,融云SDK已申请内存,开发者无需重新申请
    @param bytes_written 加密后数据的大小
    @return 0: 成功,非0: 失败。
    **/
    int CustomAudioFrameEncryptor::Encrypt(const uint8_t *payload_data, size_t payload_size,
    uint8_t *encrypted_frame, size_t *bytes_written,
    std::string mediastream_id, int mediatype) {
    //在此处实现自己的音频加密算法,示例为按位取反
    uint8_t fake_key_ = 0xff;
    for (size_t i = 0; i < payload_size; i++) {
    encrypted_frame[i] = payload_data[i] ^ fake_key_;
    }
    *bytes_written = payload_size;
    return 0;
    }

    /**
    *计算加密后数据的长度
    @param frame_size 明文大小
    @return size_t 密文长度
    **/
    size_t CustomAudioFrameEncryptor::GetMaxCiphertextByteSize(size_t frame_size, std::string mediastream_id,
    int mediatype) {
    //加密之后数据帧大小
    return frame_size;
    }
  • 音频解密示例代码:

    /**
    开发者定义解密方法
    @param encrypted_frame 解密前的数据起始地址
    @param encrypted_frame_size 解密前的数据大小
    @param frame 解密后的数据起始地址,融云SDK已申请内存,开发者无需重新申请
    @param bytes_written 解密后数据的大小
    @return 0: 成功,非0: 失败。
    **/
    int CustomAudioFrameDecryptor::Decrypt(const uint8_t *encrypted_frame, size_t encrypted_frame_size,
    uint8_t *frame, size_t *bytes_written,
    std::string mediastream_id, int mediatype) {
    // 在此处实现自己的解密算法,示例为按位取反
    uint8_t fake_key_ = 0xff;
    for (size_t i = 0; i < encrypted_frame_size; i++) {
    frame[i] = encrypted_frame[i] ^ fake_key_;
    }
    *bytes_written = encrypted_frame_size;
    return 0;
    }

    /**
    计算解密后数据的长度
    @param frame_size 密文大小
    @return size_t 明文长度
    **/
    size_t CustomAudioFrameDecryptor::GetMaxPlaintextByteSize(size_t frame_size, std::string mediastream_id,
    int mediatype) {
    // 解密之后帧大小
    return frame_size;
    }

提示

视频加解密方式类似,需要在 C++ 层实现 CustomVideoFrameEncryptor 和 CustomVideoFrameDecryptor 类即可。