27、WebRTC安全:DTLS-SRTP加密、证书管理、安全最佳实践、常见安全漏洞

WebRTC 的安全性,说白了就是解决两个问题:你的音视频流会不会被偷听? 以及 跟你通话的人到底是不是他本人?

我刚开始接触 WebRTC 时,觉得这玩意儿浏览器都封装好了,安全应该不用操心。直到有一次在客户现场做演示,我用 Wireshark 抓了个包,发现媒体流居然是明文传输的……嗯,从那以后我再也不敢忽略安全配置了。

这一章,我们就来聊聊 WebRTC 的安全机制。我会从 DTLS-SRTP 加密讲起,再到证书管理、安全最佳实践,最后聊聊那些容易踩的坑。

WebRTC 安全知识体系 WebRTC 安全 DTLS-SRTP 加密 • DTLS 握手交换密钥 • SRTP 加密媒体流 • AES-128/256 加密算法 证书管理 • 自签名证书 • 指纹验证 • 证书轮换策略 安全最佳实践 常见安全漏洞

DTLS-SRTP:WebRTC 的加密基石

WebRTC 的媒体流加密,用的是 DTLS-SRTP 这套组合拳。DTLS 负责握手和密钥交换,SRTP 负责实际的媒体加密。

你可能会问:为什么不用 HTTPS 那套?因为 WebRTC 走的是 UDP,而 TLS 是基于 TCP 的。DTLS 就是 TLS 的 UDP 版本,专门为实时通信设计的。

核心流程:
  1. 双方通过信令交换 SDP,SDP 里包含 DTLS 指纹
  2. 建立 DTLS 握手,交换证书和密钥
  3. 用协商好的密钥初始化 SRTP
  4. 音视频数据通过 SRTP 加密传输

我在项目中遇到过一个问题:有些老版本的浏览器不支持 DTLS 1.2,导致握手失败。后来我们加了个降级策略,如果 DTLS 1.2 失败,就尝试 DTLS 1.0。不过现在基本不用担心了,主流浏览器都支持 DTLS 1.2 以上。

证书管理:别让证书成为你的短板

WebRTC 使用自签名证书,而不是 CA 签发的证书。为什么?因为 WebRTC 的通信双方是点对点的,不需要第三方 CA 来验证身份。验证方式是通过 指纹(fingerprint) 来完成的。

证书指纹会在 SDP 中交换。接收方拿到对方的证书后,计算其指纹,跟 SDP 里的指纹比对。一致就说明证书没被篡改。

我的建议: 证书有效期别设太长。我习惯设 30 天,然后定期轮换。虽然自签名证书没有吊销机制,但短有效期可以降低风险。

这里有个坑:有些开发者为了省事,把证书写死在代码里。我曾经见过一个项目,证书过期了还在用,结果所有通话都建立不起来。排查了半天才发现是证书的问题。

安全最佳实践:我踩过的坑和总结的经验

做了这么多年 WebRTC,我总结了几条安全铁律:

  • 强制使用 HTTPS:浏览器只有在 HTTPS 页面下才能使用 WebRTC。这是硬性要求,没得商量。
  • 信令通道必须加密:信令走 WebSocket 的话,一定要用 WSS(WebSocket Secure)。信令被篡改,整个通话就危险了。
  • 验证 ICE 候选者:不是所有 ICE 候选者都是可信的。我遇到过有人伪造 ICE 候选者,试图劫持媒体流的情况。
  • 限制 STUN/TURN 服务器访问:TURN 服务器消耗带宽,容易被滥用。加上认证机制,只允许合法用户使用。
警告: 不要在生产环境关闭加密!我见过有人为了调试方便,在代码里设置 googIPv6: false 或者关闭 DTLS。调试完一定要改回来,否则你的音视频流就是裸奔的。

常见安全漏洞:这些坑你可能会遇到

WebRTC 虽然安全机制比较完善,但用不好照样出问题。我整理了几个常见的漏洞:

漏洞类型 描述 解决方案
媒体劫持 攻击者伪造 SDP,替换自己的媒体流 使用 DTLS-SRTP,验证证书指纹
信令篡改 信令通道被中间人攻击 信令走 WSS,使用 Token 认证
STUN 反射攻击 利用 STUN 服务器进行 DDoS 限制 STUN 请求频率,使用认证
TURN 资源耗尽 恶意用户大量使用 TURN 中继 TURN 加上用户认证和配额限制
本地网络泄露 WebRTC 可能泄露内网 IP 配置 ICE 策略,限制私有 IP 暴露

我记得有一次做安全审计,发现我们的 WebRTC 应用存在 本地网络泄露 的问题。攻击者可以通过 JavaScript 获取用户的局域网 IP,进而推断出网络拓扑。解决办法是在 ICE 配置里加上 iceTransportPolicy: 'relay',强制只使用 TURN 中继。

代码示例:配置安全的 WebRTC 连接

下面是一个安全配置的示例,我习惯把这些参数写在一个配置对象里:

const peerConnectionConfig = {
  iceServers: [
    {
      urls: 'stun:stun.example.com:3478'
    },
    {
      urls: 'turn:turn.example.com:3478',
      username: 'user123',
      credential: 'tempPassword'
    }
  ],
  iceTransportPolicy: 'all', // 生产环境建议用 'relay'
  bundlePolicy: 'max-bundle',
  rtcpMuxPolicy: 'require',
  // 强制使用 DTLS
  sdpSemantics: 'unified-plan'
};

const pc = new RTCPeerConnection(peerConnectionConfig);

// 监听连接状态变化
pc.oniceconnectionstatechange = () => {
  console.log('ICE 状态:', pc.iceConnectionState);
  if (pc.iceConnectionState === 'failed') {
    // 重连逻辑
    console.warn('连接失败,尝试重连...');
  }
};
小技巧: 我习惯在 oniceconnectionstatechange 里加日志,方便排查问题。生产环境可以上报到监控系统,这样出问题能第一时间发现。

总结

WebRTC 的安全机制其实挺完善的,关键是要正确使用。DTLS-SRTP 保证了媒体流的加密,证书指纹防止了中间人攻击,再加上合理的配置和监控,基本能应对大部分安全威胁。

最后说一句:安全不是一次性的工作。随着业务发展,攻击手段也在进化。定期做安全审计,关注 WebRTC 的安全更新,才能让你的应用立于不败之地。


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