BoringSSL 集成 · SSL 库怎么接进来
DTLS 握手、证书、密钥导出,底层都靠一个密码库——BoringSSL。这一章读 rtc_base 的 openssl_stream_adapter.h:WebRTC 用 SSLStreamAdapter 接口抽象 SSL 库,OpenSSLStreamAdapter 是 BoringSSL 的落地,以及 openssl_adapter 怎么服务 TURN-over-TLS。
BoringSSL 集成 · SSL 库怎么接进来
DTLS 握手、证书、密钥导出——这些密码学重活,WebRTC 不自己造轮子,而是接一个成熟的 SSL 库:BoringSSL。这一章看它怎么被接进来,收尾第 3 部分的技术侧。
BoringSSL:Google 的 OpenSSL 分支
BoringSSL 是 Google 从 OpenSSL 分叉出来、自用的 SSL/TLS 库。Chrome、Android、以及 WebRTC 都用它。相比 OpenSSL,它更精简、更贴合 Google 的需求、API 更可控。WebRTC 的 DTLS/TLS 全靠它撑:握手的状态机、证书的解析与验证、密钥导出、加密原语,都由 BoringSSL 提供。
SSLStreamAdapter:一层抽象
WebRTC 不直接、四处散落地调 BoringSSL 的 C API,而是先包一层抽象接口 SSLStreamAdapter,再由具体实现去对接 SSL 库。真实实现是 OpenSSLStreamAdapter(rtc_base/openssl_stream_adapter.h):
// rtc_base/openssl_stream_adapter.h(节选)
class OpenSSLStreamAdapter final : public SSLStreamAdapter {
void SetIdentity(std::unique_ptr<SSLIdentity> identity) override; // 设本地证书 + 私钥
// 驱动 DTLS 握手、加解密记录、ExportKeyingMaterial 等
};「接口 + 实现」这层抽象,是 WebRTC 一贯的解耦手法。 SSLStreamAdapter 是接口(定义「一个能做 TLS/DTLS 的流该有哪些能力」),OpenSSLStreamAdapter 是它基于 BoringSSL 的落地。好处有二:
- 隔离依赖:上层的
DtlsTransportInternalImpl只依赖SSLStreamAdapter接口,不直接碰 BoringSSL 的 C API——SSL 库若要升级 / 更换,改动局限在 adapter 一层。(历史上 WebRTC 支持过不同的 SSL 后端,靠的正是这层抽象。) - 好测试:接口可以被 mock,DTLS 逻辑的测试不必真跑一个 SSL 库。
OpenSSLStreamAdapter 的活,就是把上层的请求(设证书 SetIdentity、开始握手、加解密一段数据、导出密钥)翻译成对 BoringSSL 的调用,并把 BoringSSL 的回调 / 状态翻译回上层能懂的事件。它是 WebRTC 世界和 BoringSSL 世界之间的翻译官。
两个 adapter:流式 vs 套接字
rtc_base 里其实有两个相关的 adapter,服务不同场景,别混淆:
| adapter | 服务谁 | 场景 |
|---|---|---|
OpenSSLStreamAdapter | DtlsTransport | DTLS——媒体的密钥协商(本部分主线) |
OpenSSLAdapter | 套接字 | TLS——如 TURN-over-TLS 连接 TURN 服务器 |
前者是「流适配器」,处理 DTLS 这种在既有传输之上的安全流;后者是「套接字适配器」,把一个普通 TCP 套接字包成 TLS 套接字(用于 TURN 走 TLS 穿越企业防火墙)。两者都封装 BoringSSL,只是接入点不同。
加密原语的复用
除了 DTLS/TLS,WebRTC 别处的密码学也大量复用 BoringSSL:证书的生成与指纹计算(boringssl_certificate.cc / boringssl_identity.cc)、随机数、哈希……都走 BoringSSL。一个密码库,统一供给全库的安全需求——不重复造轮子,也把「密码学正确性」这个极易出错的领域,集中托付给一个经过严格审计的库。这是安全工程的稳妥之道:密码学,能不自己写就不自己写。
小结与第 3 部分回顾
WebRTC 的 DTLS/TLS/加密原语,底层全靠 BoringSSL(Google 的 OpenSSL 分支)。它通过 SSLStreamAdapter 接口 + OpenSSLStreamAdapter 实现接入(SetIdentity 设证书、驱动握手与密钥导出),这层抽象隔离依赖、便于测试。另有 OpenSSLAdapter 服务 TURN-over-TLS。证书、指纹、随机数等也复用 BoringSSL——密码学集中托付给一个经审计的库。
第 3 部分「安全」到此完整:强制加密的双层模型 → DTLS 握手 → 证书指纹防中间人 → 密钥导出 → SRTP 加密媒体 → BoringSSL。一条 ICE 通路从明文变成了端到端加密的安全信道。
但 SRTP 是跳到跳(hop-by-hop)加密——媒体过 SFU 服务器时,服务器能解密。要做真正端到端(连服务器都看不见)的加密,还需要一层 SFrame。下一章看它,收尾第 3 部分。👉 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 库。