# BoringSSL 集成 · SSL 库怎么接进来

> DTLS 握手、证书、密钥导出，底层都靠一个密码库——BoringSSL。这一章读 rtc_base 的 openssl_stream_adapter.h：WebRTC 用 SSLStreamAdapter 接口抽象 SSL 库，OpenSSLStreamAdapter 是 BoringSSL 的落地，以及 openssl_adapter 怎么服务 TURN-over-TLS。

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

# BoringSSL 集成 · SSL 库怎么接进来

[DTLS 握手](https://daiw.org/manual/webrtc/dtls-handshake)、[证书](https://daiw.org/manual/webrtc/certificates-fingerprints)、[密钥导出](https://daiw.org/manual/webrtc/dtls-srtp-key-export)——这些密码学重活，WebRTC 不自己造轮子，而是接一个成熟的 SSL 库：**BoringSSL**。这一章看它怎么被接进来，收尾第 3 部分的技术侧。

## BoringSSL：Google 的 OpenSSL 分支

**BoringSSL** 是 Google 从 OpenSSL 分叉出来、自用的 SSL/TLS 库。Chrome、Android、以及 WebRTC 都用它。相比 OpenSSL，它更精简、更贴合 Google 的需求、API 更可控。WebRTC 的 [DTLS](https://daiw.org/manual/webrtc/dtls-handshake)/TLS 全靠它撑：握手的状态机、证书的解析与验证、[密钥导出](https://daiw.org/manual/webrtc/dtls-srtp-key-export)、加密原语，都由 BoringSSL 提供。

## SSLStreamAdapter：一层抽象

WebRTC 不直接、四处散落地调 BoringSSL 的 C API，而是先包一层**抽象接口** `SSLStreamAdapter`，再由具体实现去对接 SSL 库。真实实现是 **`OpenSSLStreamAdapter`**（`rtc_base/openssl_stream_adapter.h`）：

```cpp
// rtc_base/openssl_stream_adapter.h(节选)
class OpenSSLStreamAdapter final : public SSLStreamAdapter {
  void SetIdentity(std::unique_ptr<SSLIdentity> identity) override;  // 设本地证书 + 私钥
  // 驱动 DTLS 握手、加解密记录、ExportKeyingMaterial 等
};
```

<Callout type="info">
  **「接口 + 实现」这层抽象，是 WebRTC 一贯的[解耦手法](https://daiw.org/manual/webrtc/source-map)。** `SSLStreamAdapter` 是接口（定义「一个能做 TLS/DTLS 的流该有哪些能力」），`OpenSSLStreamAdapter` 是它基于 BoringSSL 的落地。好处有二：

  - **隔离依赖**：上层的 [`DtlsTransportInternalImpl`](https://daiw.org/manual/webrtc/dtls-handshake) 只依赖 `SSLStreamAdapter` 接口，不直接碰 BoringSSL 的 C API——SSL 库若要升级 / 更换，改动局限在 adapter 一层。（历史上 WebRTC 支持过不同的 SSL 后端，靠的正是这层抽象。）
  - **好测试**：接口可以被 mock，DTLS 逻辑的测试不必真跑一个 SSL 库。

  `OpenSSLStreamAdapter` 的活，就是把上层的请求（[设证书](https://daiw.org/manual/webrtc/certificates-fingerprints) `SetIdentity`、开始握手、加解密一段数据、[导出密钥](https://daiw.org/manual/webrtc/dtls-srtp-key-export)）翻译成对 BoringSSL 的调用，并把 BoringSSL 的回调 / 状态翻译回上层能懂的事件。它是 WebRTC 世界和 BoringSSL 世界之间的**翻译官**。
</Callout>

## 两个 adapter：流式 vs 套接字

`rtc_base` 里其实有两个相关的 adapter，服务不同场景，别混淆：

| adapter | 服务谁 | 场景 |
| --- | --- | --- |
| `OpenSSLStreamAdapter` | [`DtlsTransport`](https://daiw.org/manual/webrtc/dtls-handshake) | **DTLS**——媒体的密钥协商（本部分主线） |
| `OpenSSLAdapter` | 套接字 | **TLS**——如 [TURN-over-TLS](https://daiw.org/manual/webrtc/turn) 连接 TURN 服务器 |

前者是「流适配器」，处理 DTLS 这种在既有[传输](https://daiw.org/manual/webrtc/jsep-transport-controller)之上的安全流；后者是「套接字适配器」，把一个普通 TCP 套接字包成 TLS 套接字（用于 [TURN 走 TLS 穿越企业防火墙](https://daiw.org/manual/webrtc/turn)）。两者都封装 BoringSSL，只是接入点不同。

## 加密原语的复用

除了 DTLS/TLS，WebRTC 别处的密码学也大量复用 BoringSSL：[证书](https://daiw.org/manual/webrtc/certificates-fingerprints)的生成与指纹计算（`boringssl_certificate.cc` / `boringssl_identity.cc`）、随机数、哈希……都走 BoringSSL。**一个密码库，统一供给全库的安全需求**——不重复造轮子，也把「密码学正确性」这个极易出错的领域，集中托付给一个经过严格审计的库。这是安全工程的稳妥之道：**密码学，能不自己写就不自己写。**

## 小结与第 3 部分回顾

WebRTC 的 [DTLS](https://daiw.org/manual/webrtc/dtls-handshake)/TLS/加密原语，底层全靠 **BoringSSL**（Google 的 OpenSSL 分支）。它通过 **`SSLStreamAdapter` 接口 + `OpenSSLStreamAdapter` 实现**接入（`SetIdentity` 设证书、驱动握手与[密钥导出](https://daiw.org/manual/webrtc/dtls-srtp-key-export)），这层抽象**隔离依赖、便于测试**。另有 `OpenSSLAdapter` 服务 [TURN-over-TLS](https://daiw.org/manual/webrtc/turn)。证书、指纹、随机数等也复用 BoringSSL——**密码学集中托付给一个经审计的库**。

**第 3 部分「安全」到此完整**：[强制加密的双层模型](https://daiw.org/manual/webrtc/security-overview) → [DTLS 握手](https://daiw.org/manual/webrtc/dtls-handshake) → [证书指纹防中间人](https://daiw.org/manual/webrtc/certificates-fingerprints) → [密钥导出](https://daiw.org/manual/webrtc/dtls-srtp-key-export) → [SRTP 加密媒体](https://daiw.org/manual/webrtc/srtp-encryption) → BoringSSL。一条 [ICE 通路](https://daiw.org/manual/webrtc/network-monitoring)从明文变成了端到端加密的安全信道。

但 SRTP 是**跳到跳（hop-by-hop）**加密——媒体过 [SFU 服务器](https://daiw.org/manual/webrtc/turn)时，服务器能解密。要做**真正端到端**（连服务器都看不见）的加密，还需要一层 **SFrame**。下一章看它，收尾第 3 部分。👉 [SFrame 端到端加密](https://daiw.org/manual/webrtc/sframe)。

## 参考资料

- [1] libwebrtc 源码.`rtc_base/openssl_stream_adapter.h`（`OpenSSLStreamAdapter`、`SetIdentity`）、`rtc_base/ssl_stream_adapter.h`（接口）。
- [2] libwebrtc 源码.`rtc_base/openssl_adapter.h`（TLS 套接字）、`rtc_base/boringssl_certificate.cc`。
- [3] BoringSSL.https://boringssl.googlesource.com/boringssl/ —— Google 的 SSL 库。
