流媒体加密

更新时间: 2026/01/06 15:49:38

本文详细介绍如何在 iOS 平台上使用网易会议组件 NEMeetingKit 配置会议媒体流加密功能。为保障会议内容安全,NEMeetingKit 提供内置加密和自定义加密两种媒体流加密方案。

前提条件

开始本文操作前,请确保您已经完成了 登录鉴权 的相关配置。

方案一:内置加密配置

NEMeetingKit 提供内置的媒体流加密功能,您可通过 NEMeetingParams.encryptionConfig 进行配置,目前支持国密 SM4-ECB 算法。

使用内置加密时,同一会议中的所有参会者必须配置相同的加解密密钥,否则将无法正常收发音视频。

示例代码

Objective-C// 创建加密配置
NEEncryptionConfig *encryptionConfig = [[NEEncryptionConfig alloc] init];
encryptionConfig.mode = NEEncryptionMode.GMCryptoSM4ECB;  // 使用国密 SM4-ECB 算法
encryptionConfig.key = @"yourEncryptionKey"; // 加密密钥

NEStartMeetingParams *startParams = [[NEStartMeetingParams alloc] init];
// 设置加密配置到会议参数
startParams.encryptionConfig = encryptionConfig;
startParams.displayName = @"加密会议用户";

// 使用设置好的参数开始会议
[[NEMeetingKit getInstance].getMeetingService startMeeting:params opts:options callback:^(NSInteger resultCode, NSString *resultMsg, id result) {}];

方案二:自定义加密实现

对于需要更高安全级别的场景,NEMeetingKit 支持通过底层依赖的 音视频通话 2.0 NERTC SDK 实现自定义加密。您可以使用自己的加密算法对音频帧和视频帧进行加解密处理。

注意事项

  • 本文示例中的加解密算法仅作示范,生产环境中请使用安全的加密算法。
  • 详细的自定义加密实现请参考 NERTC SDK 流媒体加密
  • 同一会议中所有参会者必须使用相同的加解密算法和密钥。

实现步骤

  1. 监听 RTC 引擎初始化

    自定义 NEGlobalEventListener 监听器,在 RTC 实例初始化完成后设置自定义加解密:

    Objective-C#import <NERtcSDK/NERtcSDK.h>
    
    // 1. 实现全局监听器
    @interface CustomEncryptionListener : NSObject <NEGlobalEventListener>
    @property (nonatomic, strong ) CustomEncryptObserver *encryptObserver;
    @end
    
    @implementation CustomEncryptionListener
    
    - (CustomEncryptObserver *)encryptObserver {
        if (!_encryptObserver) {
            _encryptObserver = [[CustomEncryptObserver alloc] init];
        }
        return _encryptObserver;
    }
    
    - (void)beforeRtcEngineInitializeWithRoomUuid:(NSString * _Nonnull)roomUuid rtcWrapper:(NERtcWrapper * _Nonnull)rtcWrapper {
            // RTC 引擎初始化前的操作(如果需要)
    }
    
    - (void)afterRtcEngineInitializeWithRoomUuid:(NSString * _Nonnull)roomUuid rtcWrapper:(NERtcWrapper * _Nonnull)rtcWrapper {
        // RTC 引擎初始化后,开启加密
        NERtcEncryptionConfig *config = [[NERtcEncryptionConfig alloc] init];
        config.mode = NERtcEncryptionModeCustom;
        config.observer = self.encryptObserver;
        [[rtcWrapper rtcEngine] enableEncryption:true config:config];
    }
    
    - (void)beforeRtcEngineReleaseWithRoomUuid:(NSString * _Nonnull)roomUuid rtcWrapper:(NERtcWrapper * _Nonnull)rtcWrapper {
        // RTC 引擎销毁前,可执行清理工作
        NERtcEncryptionConfig *config = [[NERtcEncryptionConfig alloc] init];
        [[rtcWrapper rtcEngine] enableEncryption:false config:config];
    }
    @end
    
    
     // 2. 注册监听器(在 SDK 初始化完成后添加)
    CustomEncryptionListener *listener = [[CustomEncryptionListener alloc] init];
    [[NEMeetingKit getInstance] addGlobalEventListener: self]
    
  2. 实现自定义加解密逻辑

    实现 NERtcEnginePacketObserver 接口,在音视频帧回调中处理数据:

    Objective-C#import <NERtcSDK/NERtcSDK.h>
    
    @interface CustomEncryptObserver : NSObject <NERtcEnginePacketObserver> 
    @property (nonatomic, assign) BOOL enableAudioEncryption;
    @property (nonatomic, assign) BOOL enableVideoEncryption;
    @end
    
    @implementation CustomEncryptObserver
    // 发送音频包回调
    - (BOOL)onSendAudioPacket:(NERtcPacket *)packet {
        if (_enableAudioEncryption) {
            unsigned char *p = packet.buffer;
            unsigned char *temp = (unsigned char *)malloc(packet.size);
            uint64_t dataLength = packet.size;
            for (int i = 0; i < dataLength; i++) {
            temp[i] = ~p[i];
            }
            memcpy((unsigned char *)packet.buffer, temp, dataLength);
            free(temp);
        }
        return YES;
    }
    // 发送视频包回调
    - (BOOL)onSendVideoPacket:(NERtcPacket *)packet {
        if (_enableVideoEncryption) {
            unsigned char *p = packet.buffer;
            unsigned char *temp = (unsigned char *)malloc(packet.size);
            uint64_t dataLength = packet.size;
            for (int i = 0; i < dataLength; i++) {
            temp[i] = ~p[i];
            }
            memcpy((unsigned char *)packet.buffer, temp, dataLength);
            free(temp);
        }
        return YES;
    }
    // 接收音频包回调
    - (BOOL)onReceiveAudioPacket:(NERtcPacket *)packet {
        if (_enableAudioEncryption) {
            unsigned char *p = packet.buffer;
            unsigned char *temp = (unsigned char *)malloc(packet.size);
            uint64_t dataLength = packet.size;
            for (int i = 0; i < dataLength; i++) {
            temp[i] = ~p[i];
            }
            memcpy((unsigned char *)packet.buffer, temp, dataLength);
            free(temp);
        }
        return YES;
    }
    // 接收视频包回调
    - (BOOL)onReceiveVideoPacket:(NERtcPacket *)packet {
        if (_enableVideoEncryption) {
            unsigned char *p = packet.buffer;
            unsigned char *temp = (unsigned char *)malloc(packet.size);
            uint64_t dataLength = packet.size;
            for (int i = 0; i < dataLength; i++) {
            temp[i] = ~p[i];
            }
            memcpy((unsigned char *)packet.buffer, temp, dataLength);
            free(temp);
        }
        return YES;
    }
    @end
    
    
此文档是否对你有帮助?
有帮助
去反馈
  • 前提条件
  • 方案一:内置加密配置
  • 方案二:自定义加密实现
  • 注意事项
  • 实现步骤