15、安全与加密:DTLS-SRTP加密、TLS证书、身份认证、权限控制

说到WebRTC的安全,我其实挺感慨的。早些年做音视频通信,大家总觉得「先跑起来再说」,安全是后话。但后来我在一个金融项目里吃过亏——有人直接抓包拿到了裸RTP流,会议内容等于公开广播。从那以后,我对WebRTC的加密机制再也不敢马虎。

WebRTC从一开始就把安全写进了基因里。它强制要求所有媒体流必须加密,没有「明文模式」这个选项。今天我们就来拆解一下,这背后的四道防线:DTLS-SRTP、TLS证书、身份认证、权限控制。

核心一句话:WebRTC的安全不是可选项,是强制项。你绕不开,也不该绕开。

WebRTC 安全四层防线 DTLS-SRTP 媒体流加密 TLS 证书 信令通道加密 身份认证 用户合法性 权限控制 资源访问策略 层层递进,缺一不可 WebRTC 强制安全模型

DTLS-SRTP:媒体流的「防窃听」铠甲

先说说DTLS-SRTP。这名字看着长,其实拆开就懂了:DTLS负责握手和密钥交换,SRTP负责用这些密钥加密媒体数据。

我刚开始接触时有个疑问:为什么不用普通的TLS?后来才明白,TLS跑在TCP上,而WebRTC的媒体流走的是UDP。DTLS就是TLS的UDP版本,专门为实时场景设计的。

小提示:DTLS-SRTP的握手过程是自动完成的。你不需要手动管理密钥,浏览器和底层库帮你搞定了。但你要确保信令通道把指纹(fingerprint)正确传递给了对端。

具体流程是这样的:

  1. 双方通过信令交换各自的证书指纹(SHA-256哈希)
  2. DTLS握手在媒体通道上进行,验证证书指纹是否匹配
  3. 握手成功后,协商出SRTP的密钥材料
  4. 后续所有音视频包都用SRTP加密传输

嗯,这里要注意一个坑。我在一个跨平台项目里遇到过:Android端和iOS端的DTLS实现有细微差异,导致握手失败。排查了半天,最后发现是证书指纹的编码格式不一致——一个用了十六进制小写,另一个用了大写。这种问题,说白了就是规范没对齐。

TLS证书:信令通道的「身份证」

DTLS-SRTP保护的是媒体流,那信令通道呢?信令通道通常走WebSocket,而WebSocket的安全依赖于TLS。这就是为什么生产环境一定要用wss://而不是ws://。

我个人习惯是:所有信令服务器都配置Let's Encrypt的免费证书,配合自动续期。别为了省事用自签名证书,除非你只在局域网测试。

警告:自签名证书在Chrome上会直接导致getUserMedia失败。浏览器认为不安全的环境,连摄像头权限都不会给你。

关于证书,还有一点容易被忽略:WebRTC的DTLS握手使用的是自签名证书,而不是CA签发的证书。为什么?因为WebRTC用的是指纹验证机制——只要指纹匹配,证书是谁签的不重要。这跟HTTPS的信任模型完全不同。

我曾经在给客户做安全审计时,对方的安全主管盯着这个点问了好久:「你们用自签名证书?这不安全吧?」我解释了半天,最后画了个对比图才说清楚。你想想看,HTTPS的CA体系是为了解决「这个域名是不是真的」,而WebRTC的指纹验证是为了解决「这个对端是不是我约好的那个人」——场景不同,方案自然不同。

身份认证:谁在连接我的房间?

DTLS-SRTP和TLS解决了「通道安全」的问题,但没解决「用户身份」的问题。说白了,加密只能防止偷听,不能防止坏人进来。

身份认证这块,WebRTC本身没有内置方案,需要你在信令服务器层面实现。常见的做法有:

  • Token认证:用户登录后获取一个JWT,每次信令请求都带上
  • 房间密码:简单粗暴,适合小规模会议
  • OAuth集成:对接企业已有的认证系统

我在一个教育项目里用的是Token+房间密码双重验证。为什么?因为学生账号可能被分享出去,加上房间密码能多一层保护。虽然麻烦了点,但客户满意就行。

关键点:身份认证必须在信令层面完成。一旦用户加入了房间,后续的媒体流加密是自动的,但「让不让进」这个决策,得你自己做。

权限控制:能做什么,不能做什么

身份认证通过后,接下来就是权限控制。用户进了房间,他能做什么?

典型的权限模型包括:

  • 发言权:谁能开麦克风,谁能开摄像头
  • 屏幕共享:谁有权限发起屏幕共享
  • 录制权限:谁能录制会议内容
  • 踢人权限:谁能把其他人请出房间

我建议把权限控制设计成可配置的。比如在会议创建时,主持人可以选择「所有人可发言」或「仅主持人可发言」。这种灵活性在实际项目中非常实用。

举个例子,我在做远程医疗项目时,医生需要随时控制患者的摄像头权限——患者不能自己关闭摄像头,因为医生需要持续观察。这种场景下,权限控制就不是「能不能」的问题,而是「必须这样」的问题。

实现建议:权限控制最好放在信令服务器上做,而不是依赖客户端。客户端可以被篡改,服务器端才是可信的。

避坑指南:我踩过的几个坑

做WebRTC安全,有些坑我替你们踩过了:

  • 证书指纹不匹配:检查大小写、冒号分隔符、Base64编码格式。我遇到过因为多了一个空格导致握手失败的案例。
  • DTLS超时设置:弱网环境下DTLS握手可能超时。建议把超时时间设长一点,比如10秒,而不是默认的5秒。
  • 权限提升漏洞:客户端发来的权限请求,服务器端一定要二次校验。别信客户端的「我是主持人」这种声明。
  • 日志泄露:别把完整的SDP信息打到日志里,里面包含指纹和ICE候选信息。我曾经在客户现场调试时,发现日志文件里明文记录了所有连接信息——赶紧改了。

安全这件事,说白了就是一层一层地加锁。DTLS-SRTP锁住了媒体流,TLS锁住了信令通道,身份认证锁住了大门,权限控制锁住了房间里的每个功能。少一层,你的系统就可能出问题。

我记得有一次线上事故,就是因为忘了在信令服务器上做身份认证,结果有人直接构造了WebSocket请求混进了会议室。虽然媒体流是加密的,但人家能听到所有对话——这跟没加密有什么区别?从那以后,我每次做架构设计,都会把安全四层防线画出来,逐条确认。


公众号:蓝海资料掘金营,微信deep3321