# 安全总览 · 强制加密与 DTLS-SRTP

> WebRTC 强制加密媒体，没有明文选项。这一章讲清它的双层安全模型：DTLS 负责握手协商密钥，SRTP 负责加密每个媒体包（DTLS-SRTP,RFC 5764）；为什么废弃了旧的 SDES；支持哪些加密套件；以及 DTLS 在 WebRTC 里的两个用途。

- 作者：David（道雾轩）
- 专栏：音视频与 WebRTC 详解（https://daiw.org/manual/webrtc.md）
- 最后更新：2026-07-14
- 原文：https://daiw.org/manual/webrtc/security-overview
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 安全总览 · 强制加密与 DTLS-SRTP

[ICE 打通了一条路](https://daiw.org/manual/webrtc/network-monitoring)，但那还是**明文**——谁在链路上都能偷看、篡改。第 3 部分讲 WebRTC 怎么把这条路变**安全**。而 WebRTC 在安全上有一条不容商量的底线：**强制加密**。

## 没有明文选项

`g3doc/srtp.md` 开门见山：

> WebRTC **mandates** encryption of media by means of the Secure Realtime Protocol, or SRTP.

<Callout type="info">
  **WebRTC 强制加密媒体——这不是可选项，是硬性规定。** 你无法用 WebRTC 建立一个「明文」的媒体连接（唯一例外是调试用的 `disable_encryption` 内部选项，生产中绝不可用）。这和很多传统 VoIP 系统「加密是加分项」的态度截然不同。原因很直接：**实时通信传的是人的声音和面孔，隐私不容妥协。** 把加密做成地基而非配件，是 WebRTC 一个值得称道的设计立场——[从一开始就是这样](https://daiw.org/manual/webrtc/what-is-webrtc)。
</Callout>

## 双层模型：DTLS 谈密钥，SRTP 加密媒体

WebRTC 的媒体加密，由**两个协议分工**完成：

| 协议 | 负责 | RFC |
| --- | --- | --- |
| **DTLS** | **握手、协商密钥**（以及做数据通道的传输） | RFC 6347 |
| **SRTP** | **用密钥加密 / 解密每个媒体包** | RFC 3711 |

它们的配合叫 **DTLS-SRTP**(RFC 5764):

<Callout type="info">
  **DTLS-SRTP 的分工：用一次 DTLS 握手，协商出一套密钥；再用这套密钥，让 SRTP 去加密海量的媒体包。** 为什么不直接用 DTLS 加密媒体？因为 [DTLS](https://daiw.org/manual/webrtc/dtls-handshake) 的记录层是为「可靠的握手 / 控制消息」设计的，开销和语义都不适合[实时 RTP 媒体](https://daiw.org/manual/webrtc/source-map)（海量小包、可乱序、可丢弃）。[SRTP](https://daiw.org/manual/webrtc/srtp-encryption) 则是**专为 RTP 量身定做**的加密——轻量、逐包、抗重放。于是分工：**DTLS 干「谈密钥」这种一次性的重活（[握手](https://daiw.org/manual/webrtc/dtls-handshake)），SRTP 干「加密每个包」这种高频的累活（[加密](https://daiw.org/manual/webrtc/srtp-encryption)）。** 各展所长。
</Callout>

顺带一提，`g3doc/srtp.md` 特意说明：**旧的 SDES 密钥协商（RFC 4568，直接把密钥写进 SDP）已不再支持**——因为把密钥明文放进[信令](https://daiw.org/manual/webrtc/call-lifecycle)不安全（信令可能被窥探）。DTLS-SRTP 用握手在**媒体通路本身**上协商密钥，密钥永不出现在信令里，安全得多。

## 支持的加密套件

`g3doc/srtp.md` 列出实现支持的 [SRTP 加密套件](https://daiw.org/manual/webrtc/srtp-encryption)：

- **`SRTP_AES128_CM_HMAC_SHA1_80`** —— 经典套件（AES-128 计数器模式 + HMAC-SHA1 认证），默认。
- **`SRTP_AEAD_AES_128_GCM`** / **`SRTP_AEAD_AES_256_GCM`** —— AEAD（带认证的加密）套件，更现代。

套件在 [DTLS 握手](https://daiw.org/manual/webrtc/dtls-handshake)时通过 DTLS-SRTP 扩展协商确定。文档还提到 `SRTP_AES128_CM_HMAC_SHA1_32`（更短的认证标签）默认关闭，仅在特定场景（纯音频）启用——这些细节由 [`CryptoOptions`](https://daiw.org/manual/webrtc/factory-and-context) 控制。

## DTLS 的两个用途

最后厘清一点（来自 `g3doc/dtls_transport.md`）：WebRTC 里 **DTLS 有两个用途**，别只记住加密：

1. **为 SRTP 协商密钥**（DTLS-SRTP）——就是本部分主线。
2. **作为[数据通道](https://daiw.org/manual/webrtc/data-channel-controller)的传输层**——[SCTP 跑在 DTLS 上](https://daiw.org/manual/webrtc/data-channel-controller)（[第 8 部分](https://daiw.org/manual/webrtc/source-map)），数据通道的加密直接靠 DTLS 记录层（数据不是 RTP，不需要 SRTP）。

所以一条 [BUNDLE 传输](https://daiw.org/manual/webrtc/jsep-transport-controller)上，DTLS 既给音视频提供 SRTP 密钥，又直接承载数据通道——**一次 DTLS 握手，同时服务两种媒体**。

## 小结与下一章

WebRTC **强制加密媒体**（SRTP，无明文选项）。安全是**双层模型**：**DTLS 握手协商密钥**，**SRTP 用密钥加密每个媒体包**，合称 **DTLS-SRTP**(RFC 5764)——DTLS 干一次性的谈密钥、SRTP 干高频的逐包加密，各展所长。旧的 **SDES 已废弃**（密钥不该进信令）。套件有 `AES128_CM_HMAC_SHA1_80`（默认）与 GCM 系列。DTLS 还兼做[数据通道](https://daiw.org/manual/webrtc/data-channel-controller)的传输。

第一步是 **DTLS 握手**——它怎么在[刚打通的 ICE 通路](https://daiw.org/manual/webrtc/p2p-transport-channel)上，和明文的 STUN、SRTP 包共处一条路，建立起安全信道？下一章细看。👉 [DTLS 握手](https://daiw.org/manual/webrtc/dtls-handshake)。

## 参考资料

- [1] libwebrtc 源码.`g3doc/srtp.md`（强制加密、DTLS-SRTP、套件、SDES 废弃）。
- [2] libwebrtc 源码.`g3doc/dtls_transport.md`（DTLS 两用途）、`api/crypto/crypto_options.h`。
- [3] IETF RFC 5764「DTLS-SRTP」、RFC 3711「SRTP」、RFC 6347「DTLS」。
