自定义加密
在实时音视频互动中,开发者可选择对媒体流进行加密,从而保障用户的数据安全。融云提供两套加密方案:
- SDK 内置 SRTP 安全实时传输协议,即协议层的标准加密方式。以开关形式提供,使用简单。
- 开发者对媒体数据的自定义加密。即加解密完全由开发者实现,融云服务只对数据做转发,适用于对安全性有特殊要求的客户。此类加密方式,服务端无法做合流处理,所以不适用于直播。
- 使用自定义加密后,无法使用部分 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 类即可。