21、WebRTC安全:HTTPS与WSS、媒体加密(SRTP)、身份验证、防篡改机制

说到WebRTC的安全,我得先跟你掏心窝子说一句:这不是可选项,是必选项。浏览器对WebRTC的安全要求非常严格——不信你试试在HTTP页面上调getUserMedia,控制台直接给你报错。

为什么会这样?因为实时通信涉及音视频流,一旦被窃听或篡改,后果很严重。我早年做第一个WebRTC项目时就吃过亏,当时觉得本地测试无所谓,结果Chrome升级后直接罢工……嗯,从那以后我再也不敢忽视安全配置了。

核心要点:WebRTC强制要求安全上下文(HTTPS或localhost),媒体流使用SRTP加密,信令通道必须走WSS。

21.1 HTTPS与WSS:安全通信的基石

WebRTC在浏览器中运行时,页面本身必须通过HTTPS加载。这不是我定的规矩,是W3C规范强制要求的。你想想看,如果页面是HTTP的,中间人攻击者可以随意替换JavaScript代码,那后续所有加密都白搭。

信令通道同样需要加密。WebSocket的加密版本叫WSS(WebSocket Secure),说白了就是ws://换成wss://。我个人习惯在生产环境中一律使用WSS,哪怕只是传输一些元数据。

协议 加密 WebRTC要求
HTTP ❌ 不允许
HTTPS TLS ✅ 必须
WS ❌ 不允许
WSS TLS ✅ 必须

小技巧:本地开发时可以用localhost或127.0.0.1,浏览器对这两个地址豁免HTTPS要求。但部署到公网,必须配证书。

21.2 媒体加密:SRTP与DTLS

WebRTC的媒体加密用的是SRTP(安全实时传输协议)。它是在RTP基础上加了加密和认证功能。密钥交换则通过DTLS(数据报传输层安全协议)完成。

整个流程是这样的:

  1. 双方建立连接后,先进行DTLS握手
  2. 握手过程中协商出SRTP的密钥
  3. 后续所有音视频数据都用SRTP加密传输

我记得有一次调试一个通话质量问题时,发现媒体流一直不通。查了半天,原来是DTLS握手失败了——证书不匹配。所以啊,DTLS握手是媒体加密的第一道关卡,必须确保两端证书配置正确。

注意:SRTP只加密媒体内容,不加密RTP头部。也就是说,有人能看到你在通话,但听不到内容。如果你连通话行为都想隐藏,需要额外使用Tor之类的匿名网络。

21.3 身份验证:确保对方是本人

加密解决了「别人听不到」的问题,但没解决「对方是谁」的问题。身份验证需要我们在应用层自己实现。

常见的做法是:

  • Token认证:用户登录后获取JWT,信令消息中携带Token
  • 房间密码:加入特定房间需要密码
  • 证书指纹验证:在DTLS握手时验证对端的证书指纹

我曾经在一个多方会议项目中,只做了Token认证,没做证书指纹验证。结果有人伪造了身份混进会议室……虽然媒体流是加密的,但对方能听到所有讨论。从那以后,我坚持双重验证:应用层Token + DTLS指纹。

// 获取本地证书指纹
const pc = new RTCPeerConnection();
const fingerprint = await pc.getStats().then(stats => {
  // 从stats中提取证书指纹
  // 发送给远端进行比对
});

// 验证远端指纹
pc.oniceconnectionstatechange = () => {
  if (pc.iceConnectionState === 'connected') {
    // 获取远端证书指纹并比对
  }
};

21.4 防篡改机制:数据完整性保护

加密能防窃听,但防不了篡改。SRTP本身带有消息认证码(MAC),可以检测数据是否被修改。但信令通道的数据完整性需要我们自己保证。

我常用的方法:

  • 消息签名:每条信令消息附带HMAC签名
  • 序列号校验:防止重放攻击
  • 时间戳验证:过期消息直接丢弃

避坑指南:我曾经遇到过一个问题——信令消息被中间人截获后重放,导致房间内出现多个重复的加入请求。后来加了序列号和时间戳双重校验,才彻底解决。

21.5 知识体系总览

下面这张图把WebRTC安全的核心模块串起来了。你可以看到,安全不是单一技术,而是一整套组合拳。

WebRTC安全体系 传输层安全 HTTPS(页面) + WSS(信令) + DTLS(密钥交换) 媒体加密 SRTP加密音视频流 + SRTCP加密控制流 身份验证 Token认证 + 证书指纹验证 + 房间密码 防篡改机制 消息签名(HMAC) + 序列号校验 + 时间戳验证

21.6 实战建议

说了这么多理论,最后给你几条我踩坑踩出来的建议:

  • 证书别用自签名的:浏览器不认,DTLS握手会失败。用Let's Encrypt免费证书就行
  • 信令通道也要防重放:别以为WSS加密了就万事大吉,应用层校验不能省
  • 定期轮换密钥:长时间通话建议每隔一段时间重新做DTLS握手
  • 日志别记录密钥:我见过有人把SRTP密钥打日志里……这是灾难

一句话总结:WebRTC安全就像盖房子——HTTPS/WSS是地基,SRTP是墙壁,身份验证是门锁,防篡改是监控。少任何一个,房子都不安全。

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