自定义加解密
在实时音视频互动中,您可以选择对媒体流进行加密,从而保障数据安全。融云提供两套加密方案:
- SDK 内置 SRTP 加密:使用安全实 时传输协议,是协议层的标准加密方式。以开关形式提供,使用简单。
- 自定义加解密:由您完全实现加解密算法,融云服务只对数据做转发,适用于对安全性有特殊要求的场景。
自定义加密限制
- 使用自定义加密后,服务端无法做合流处理,因此不适用于直播场景。
- 无法使用部分 RTC 服务端功能,包括:云端录制、云端截图、内容审核、云播放器。
- 若使用自定义加密,需要确保发送端和接收端的加解密算法一致,否则会无法正常通话。
- 自定义加密可分别针对音频或视频的原始数据执行,音频和视频的加密算法可以独立设置。
- 无论何种加密方式,都会对客户端、服务器造成额外的资源消耗,在低性能设备上可能会影响体验。
SRTP 加密
SRTP 开关
您可以在加入音视频房间前,在 RCRTCEngine 的 Config 中打开 SRTP 开关。
接口原型
Objective C
@property (nonatomic, assign) BOOL enableSRTP;
参数说明
| 属性 | 类型 | 说明 |
|---|---|---|
enableSRTP | BOOL | 是否启用 SRTP 加密。YES 为启用,NO 为关闭。默认为 NO。 |
代码示例
Objective C
#import <RongRTCLib/RongRTCLib.h>
// 加入房间前启用 SRTP 加密
[RCRTCEngine sharedInstance].config.enableSRTP = YES;
自定义加密
实现流程
实现自定义加解密需要以下两个步骤:
- 实现加解密代理:分别实现 RCRTCCustomizedEncryptorDelegate 和 RCRTCCustomizedDecryptorDelegate 协议。
- 设置代理:将实现的代理设置到 RTCLib SDK 中。
步骤 1:实现自定义加解密代理
RTCLib SDK 在 RCRTCCryptoDelegate.h 文件中提供了 RCRTCCustomizedEncryptorDelegate 和 RCRTCCustomizedDecryptorDelegate 两个加解密代理协议。您可以通过实现这些协议来获取需要加解密的媒体流数据,并在对应的方法中实现自定义的加解密逻辑。
实现加密代理
实现 RCRTCCustomizedEncryptorDelegate 的加密回调
接口原型
Objective C
- (int)EncryptPayloadData:(const uint8_t *)payloadData
payloadSize:(size_t)payloadSize
encryptedFrame:(uint8_t *)encryptedFrame
bytesWritten:(size_t *)bytesWritten
mediastreamId:(NSString *)mediastreamId
mediaType:(int)mediaType;
参数说 明
| 参数 | 类型 | 说明 |
|---|---|---|
payloadData | const uint8_t * | 待加密的原始媒体数据。 |
payloadSize | size_t | 原始媒体数据的大小。 |
encryptedFrame | uint8_t * | 加密后的数据缓冲区。 |
bytesWritten | size_t * | 实际写入加密数据的字节数。 |
mediastreamId | NSString * | 媒体流 ID。 |
mediaType | int | 媒体类型,1 为音频,2 为视频。 |
返回值
| 类型 | 说明 |
|---|---|
int | 加密结果。返回 0 表示成功,其他值表示失败。 |
实现 RCRTCCustomizedEncryptorDelegate 的加密后数据大小的回调
接口原型
Objective C
- (size_t)GetMaxCiphertextByteSize:(size_t)frameSize
mediastreamId:(NSString *)mediastreamId
mediaType:(int)mediaType;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
frameSize | size_t | 原始帧数据的大小。 |
mediastreamId | NSString * | 媒体流 ID。 |
mediaType | int | 媒体类型,1 为音频,2 为视频。 |
返回值
| 类型 | 说明 |
|---|---|
size_t | 加密后数据的最大字节数。 |
代码示例
Objective C
#import <RongRTCLib/RongRTCLib.h>
@interface CustomCrypto : NSObject <RCRTCCustomizedEncryptorDelegate, RCRTCCustomizedDecryptorDelegate>
@end
@implementation CustomCrypto
- (int)EncryptPayloadData:(const uint8_t *)payloadData
payloadSize:(size_t)payloadSize
encryptedFrame:(uint8_t *)encryptedFrame
bytesWritten:(size_t *)bytesWritten
mediastreamId:(NSString *)mediastreamId
mediaType:(int)mediaType {
// 示例:使用简单的异或运算进行加密
uint8_t encryptionKey = 0x88;
for (size_t i = 0; i < payloadSize; i++) {
encryptedFrame[i] = payloadData[i] ^ encryptionKey;
}
*bytesWritten = payloadSize;
return 0;
}
- (size_t)GetMaxCiphertextByteSize:(size_t)frameSize
mediastreamId:(NSString *)mediastreamId
mediaType:(int)mediaType {
// 在这个简单示例中,加密后的数据大小与原始数据相同
return frameSize;
}
@end
实现解密代理
实现 RCRTCCustomizedDecryptorDelegate 的解密回调
接口原型
Objective C
- (int)DecryptFrame:(const uint8_t *)encryptedFrame
frameSize:(size_t)encryptedFrameSize
frame:(uint8_t *)frame
bytesWritten:(size_t *)bytesWritten
mediastreamId:(NSString *)mediastreamId
mediaType:(int)mediaType;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
encryptedFrame | const uint8_t * | 待解密的加密数据。 |
encryptedFrameSize | size_t | 加密数据的大小。 |
frame | uint8_t * | 解密后的数据缓冲区。 |
bytesWritten | size_t * | 实际写入解密数据的字节数。 |
mediastreamId | NSString * | 媒体流 ID。 |
mediaType | int | 媒体类型,1 为音频,2 为视频。 |
返回值
| 类型 | 说明 |
|---|---|
int | 解密结果。返回 0 表示成功,其他值表示失败。 |
实现 RCRTCCustomizedDecryptorDelegate 的解密后数据大小的回调
接口原型
Objective C
- (size_t)GetMaxPlaintextByteSize:(size_t)frameSize
mediastreamId:(NSString *)mediastreamId
mediaType:(int)mediaType;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
frameSize | size_t | 加密帧数据的大小。 |
mediastreamId | NSString * | 媒体流 ID。 |
mediaType | int | 媒体类型,1 为音频,2 为视频。 |
返回值
| 类型 | 说明 |
|---|---|
size_t | 解密后数据的最大字节数。 |
代码示例
Objective C
- (int)DecryptFrame:(const uint8_t *)encryptedFrame
frameSize:(size_t)encryptedFrameSize
frame:(uint8_t *)frame
bytesWritten:(size_t *)bytesWritten
mediastreamId:(NSString *)mediastreamId
mediaType:(int)mediaType {
// 示例:使用与加密相同的异或运算进行解密
uint8_t decryptionKey = 0x88;
for (size_t i = 0; i < encryptedFrameSize; i++) {
frame[i] = encryptedFrame[i] ^ decryptionKey;
}
*bytesWritten = encryptedFrameSize;
return 0;
}
- (size_t)GetMaxPlaintextByteSize:(size_t)frameSize
mediastreamId:(NSString *)mediastreamId
mediaType:(int)mediaType {
// 在这个简单示例中,解密后的数据大小与加密数据相同
return frameSize;
}
步骤 2:设置代理
实现加解密代理后,需要将代理设置到 RTCLib SDK 中。您可以分别为音频和视频设置不同的加解密代理,也可以使用同一个代理对象。
代码示例
Objective C
#import <RongRTCLib/RongRTCLib.h>
// 创建自定义加解密实现实例
CustomCrypto *cryptoImpl = [[CustomCrypto alloc] init];
// 设置音频加解密代理
[[RCRTCEngine sharedInstance] setAudioCustomizedEncryptorDelegate:cryptoImpl];
[[RCRTCEngine sharedInstance] setAudioCustomizedDecryptorDelegate:cryptoImpl];
// 设置视频加解密代理
[[RCRTCEngine sharedInstance] setVideoCustomizedEncryptorDelegate:cryptoImpl];
[[RCRTCEngine sharedInstance] setVideoCustomizedDecryptorDelegate:cryptoImpl];