跳到主要内容

自定义加密

在音视频通话场景中,为保障用户的数据安全,开发者可对媒体流加密。

加密方式

开发者对媒体数据的自定义加密,即加解密完全由开发者实现,融云服务只对数据做转发。该方法适用于对安全性有特殊要求的客户。

自定义加密限制

使用自定义加密后,将无法使用部分 RTC 服务端功能,包括云端录制云端截图内容审核云播放器

提示
  • 若使用自定义加密,需要确保发送端和接收端的加解密算法一致,否则会无法正常通话。
  • 由于数据量大,考虑性能原因,自定义的加密算法需要在 C++ 层实现。
  • 无论何种加密方式,都会对客户端、服务器造成额外的资源消耗,在低性能设备上可能会影响体验。

具体步骤

步骤 1:发起呼叫时开启自定义加密

Java
        //开启加密
boolean isEncrypted = true;
RCCallPlusEncryption encryption = new RCCallPlusEncryption(isEncrypted);
RCCallPlusOption option = RCCallPlusOption.Builder.create()
.setCallPlusEncryption(encryption)
//其他配置...
.build();

List<String> userIds = new ArrayList<>();
userIds.add(remoteUserId);
//发起呼叫
RCCallPlusClient.getInstance().startCall(userIds, RCCallPlusType.PRIVATE, RCCallPlusMediaType.VIDEO,option);

步骤 2:配置 NDK 环境

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

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

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

步骤 4:实现加解密逻辑

通过在 C++ 层实现 CustomAudioFrameEncryptorCustomAudioFrameDecryptor 类即可实现音频加解密功能:

  • 音频加密示例代码:

    cpp
    /**
    自定义加密方法
    @param payload_data 加密前的数据起始地址
    @param payload_size 加密前的数据大小
    @param encrypted_frame 加密后的数据起始地址,融云SDK已申请内存,开发者无需重新申请
    @param bytes_written 加密后数据的大小
    @param mediastream_id 当前音频或视频流的唯一标识
    @param mediatype 媒体类型,0为"audio" 1为"video"
    @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 明文大小
    @param mediastream_id 当前音频或视频流的唯一标识
    @param mediatype 媒体类型,0为"audio" 1为"video"
    @return size_t 密文长度
    **/
    size_t CustomAudioFrameEncryptor::GetMaxCiphertextByteSize(size_t frame_size, std::string mediastream_id,
    int mediatype) {
    //加密之后数据帧大小
    return frame_size;
    }
  • 音频解密示例代码:

    cpp
    /**
    开发者定义解密方法
    @param encrypted_frame 解密前的数据起始地址
    @param encrypted_frame_size 解密前的数据大小
    @param frame 解密后的数据起始地址,融云SDK已申请内存,开发者无需重新申请
    @param bytes_written 解密后数据的大小
    @param mediastream_id 当前音频或视频流的唯一标识
    @param mediatype 媒体类型,0为"audio" 1为"video"
    @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 密文大小
    @param mediastream_id 当前音频或视频流的唯一标识
    @param mediatype 媒体类型,0为"audio" 1为"video"
    @return size_t 明文长度
    **/
    size_t CustomAudioFrameDecryptor::GetMaxPlaintextByteSize(size_t frame_size, std::string mediastream_id,
    int mediatype) {
    // 解密之后帧大小
    return frame_size;
    }

提示

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