17、WebRTC安全机制:DTLS-SRTP加密、证书管理与指纹验证、信令通道的安全(WSS/HTTPS)、常见安全攻击与防范

聊到WebRTC的安全,我得先跟你掏个底——WebRTC从一开始就把安全写进了基因里。它不像某些协议那样,安全是后加的补丁。WebRTC强制要求所有媒体流必须加密,这一点没得商量。

我个人习惯把WebRTC的安全体系拆成三层来看:

  • 传输层安全:DTLS-SRTP加密
  • 身份层安全:证书管理与指纹验证
  • 信令层安全:WSS/HTTPS

这三层缺一不可。咱们一层一层说。

WebRTC 安全三层体系 第一层:传输层安全 DTLS 握手 → SRTP 密钥派生 → 媒体流加密 强制加密,无明文模式 第二层:身份层安全 自签名证书 → 指纹生成 → 指纹交换与验证 防止中间人攻击(MITM) 第三层:信令层安全 WSS(WebSocket Secure)+ HTTPS 信令通道加密,防止SDP/ICE信息泄露

DTLS-SRTP:媒体流的加密基石

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

DTLS是TLS的UDP版本。因为WebRTC的媒体走的是UDP,所以不能用传统的TLS(那是给TCP用的)。DTLS就是在UDP上实现了类似TLS的握手流程。

握手完成后,双方协商出一个主密钥。然后SRTP用这个密钥,对每一帧视频、每一段音频进行加密。加密算法通常是AES-128或AES-256。

关键点:WebRTC强制要求使用DTLS-SRTP。没有「明文模式」这个选项。你想想看,如果视频通话能被第三方监听,那这技术谁敢用?

我在项目中遇到过一件事:有个同事想调试媒体流,问我能不能关掉加密,方便抓包分析。我说不行,WebRTC底层就不支持。后来我们改用chrome://webrtc-internals来查看内部状态,配合Wireshark的DTLS解析功能,照样能调试。

证书管理与指纹验证

DTLS握手时,双方需要出示证书。WebRTC用的是自签名证书,不是CA签发的。为什么?因为WebRTC的场景是点对点,没有统一的CA体系。

那怎么信任对方呢?靠指纹(fingerprint)

流程是这样的:

  1. 每个PeerConnection在创建时,内部会生成一个自签名证书
  2. 从证书中计算出一个哈希值,这就是指纹
  3. 指纹被写入SDP的a=fingerprint:...字段
  4. 对方收到SDP后,提取指纹,在DTLS握手时验证证书是否匹配

说白了,就是信令通道帮你传递了证书的「摘要」,然后你在DTLS握手时核对这个摘要。

小技巧:你可以通过RTCPeerConnection.getLocalCertificates()拿到当前使用的证书。我个人习惯在调试时打印指纹,确认两端是否匹配。

我曾经踩过一个坑:在Chrome和Safari之间做互通测试时,发现Safari生成的证书指纹算法是SHA-256,而Chrome默认也是SHA-256,但某些旧版本Chrome用的是SHA-1。两边指纹算法不一致,握手失败。后来统一升级浏览器版本才解决。

信令通道的安全:WSS与HTTPS

信令通道是WebRTC的「指挥中心」。SDP、ICE候选、指纹……这些敏感信息都在信令通道里传输。如果信令通道被劫持,攻击者可以替换指纹,从而实施中间人攻击。

所以,信令通道必须加密

  • 如果信令走WebSocket,必须用WSS(WebSocket Secure)
  • 如果信令走HTTP,必须用HTTPS
  • 浏览器还要求页面本身也是HTTPS,否则WebRTC API会被禁用

你想想看,如果信令通道是明文的,攻击者截获SDP后,把你的指纹换成他自己的,然后他就能在中间解密你的媒体流。这就是典型的MITM攻击。

警告:开发环境下可以用localhost绕过HTTPS限制,但生产环境必须全链路HTTPS/WSS。不要心存侥幸。

常见安全攻击与防范

我整理了几种WebRTC常见的攻击方式,以及对应的防范措施:

攻击类型 攻击方式 防范措施
中间人攻击(MITM) 替换SDP中的指纹,劫持DTLS握手 指纹验证 + 信令通道加密
媒体流窃听 抓取UDP包,尝试解密SRTP DTLS-SRTP强制加密,密钥不暴露
STUN/TURN反射攻击 利用STUN服务器放大流量,攻击第三方 配置STUN/TURN的速率限制和认证
信令劫持 劫持WebSocket连接,篡改SDP WSS + Token认证 + 消息签名
ICE欺骗 伪造ICE候选,诱导连接恶意节点 ICE候选验证 + 白名单机制

嗯,这里要注意一点:WebRTC的安全是端到端的。即使TURN服务器中转媒体流,它也看不到明文内容,因为密钥只在两端持有。TURN服务器只是帮你转发加密后的数据包。

核心原则:永远不要信任信令通道传来的任何数据,除非你能验证它。指纹验证就是WebRTC给你的「信任锚点」。

我曾经在做一个视频会议项目时,遇到过一种攻击:攻击者伪造了ICE候选,诱导客户端连接到一个恶意节点。虽然媒体流是加密的,但攻击者可以收集到连接元数据(谁在和谁通话、通话时长等)。后来我们在信令服务器上加了ICE候选的签名验证,才彻底堵住这个漏洞。

最后总结一句:WebRTC的安全机制不是可选项,是必选项。DTLS-SRTP、指纹验证、WSS/HTTPS,这三者构成了一个完整的信任链。少一个,整个安全体系就崩塌了。