作者 进学
审校 泰一
DTLS (Datagram Transport Layer Security) 基于 UDP 场景下数据包可能丢失或重新排序的现实情况下 为 UDP 定制和改进的 TLS 协议。在 WebRTC 中使用 DTLS 的地方包括两部分 协商和管理 SRTP 密钥和为 DataChannel 提供加密通道。
本文结合实际数据包分析 WebRTC 使用 DTLS 进行 SRTP 密钥协商的流程。并对在实际项目中使用 DTLS 遇到的问题进行总结。
DTLS 协议简介在分析 DTLS 在 WebRTC 中的应用之前 先介绍下 DTLS 协议的基本原理。
DTLS 协议由两层组成: Record 协议 和 Handshake 协议
TLS 握手协议流程如下 参考 RFC5246
DTLS 握手协议流程如下 参考 RFC6347
TLS 和 DTLS 的握手过程基本上是一致的 差别以及特别说明如下
RecordLayer 协议是和 DTLS 传输相关的协议 UDP 之上是 RecordLayer RecordLayer 之上是 Handshake 或 ChangeCipherSpec 或 ApplicationData。RecordLayer 协议定义参考 RFC4347 实际上有三种 RecordLayer 的包:
没有明确的字段说明是哪种消息 不过可以根据上下文以及内容判断。比如 ChangeCipherSpec 是可以通过类型 它肯定是一个 Plaintext。除了 Finished 的其他握手 一般都是 Plaintext。
SRTP 密钥协商角色协商在 DTLS 协议 通信的双方有 Client 和 Server 之分。在 WebRTC 中 DTLS 协商的身份是在 SDP 中描述的。描述如下 参考 SDP-Anatomy 中 DTLS 参数
a setup:active
setup 属性在 RFC4145
setup:active 作为 client 主动发起协商
setup:passive, 作为 sever 等待发起协商
setup:actpass, 作为 client 主动发起协商。作为 server 等待发起协商。
ClienHello 和 ServerHello 协商 DTLS 的 Version、CipherSuites、Random、以及 Extensions。
在 Hello 消息中加密套接字使用 IANA 中的注册的名字。IANA 名字由 Protocol Key Exchange Algorithm Authentication Algorithm Encryption Algorithm Hash Algorithm 的描述组成。例如 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 的含义如下
加密套接字在 ciphersuite.info 可以查到。在查到 IANA 名字的同时 也可以查到在 OpenSSL 中的名字。TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 在 OpenSSL 中的名字为 ECDHE-RSA-AES128-GCM-SHA256
Note: 关于 Authentication (认证)、KeyExchange (密钥交换)、Encryption (加密)、MAC (Message Authentication Code) 消息摘要等 可以参考 RSA 密钥协商。
DTLS 的扩展协议 是在 ClientHello 和 ServerHello 的 Extensions 信息中指定的 所有的 TLS 扩展参考 TLS Extensions。下面列出几个 WebRTC 用到的扩展
除了这些扩展协议 和 SRTP 密钥导出相关的还有
RFC5705: Keying Material Exporters for Transport Layer Security (TLS) DTLS 如何从 MasterSecret 导出 Key 比如 SRTP 的 Key。
RFC5764: DTLS Extension to Establish Keys for the SRTP DTLS 的 use_srtp 扩展的详细规范 包括 ClientHello 扩展定义、Profile 定义、Key 的计算。
身份验证 - Certificate数字证书是由一些公认可信的证书颁发机构签发的 不易伪造。数字证书可以用于接收者验证对端的身份 接收者收到某个对端的证书时 会对签名颁发机构的数字签名进行检查 一般来说 接收者事先就会预先安装很多常用的签名颁发机构的证书 含有公开密钥 利用预先的公开密钥可以对签名进行验证。
Server 端通过 Hello 消息 协商交换密钥的方法后 将 Server 证书发送给 Client 用于 Client 对 Server 的身份进行校验。Server 发送的证书必须适用于协商的 KeyExchange 使用的加密套接字 以及 Hello 消息扩展中描述的 Hash/Signature 算法对。
在 WebRTC 中 通信的双方通常将无法获得由知名根证书颁发机构 (CA) 签名的身份验证证书 自签名证书通常是唯一的选择。RFC4572 定义一种机制 通过在 SDP 中增加自签名证书的安全哈希 称为 证书指纹 在保证 SDP 安全传输的前提下 如果提供的证书的指纹与 SDP 中的指纹匹配 则可以信任自签名证书。在实际的应用场景中 SDP 在安全的信令通道 (https) 完成交换的 SDP 的安全完整是可以做到的。这样在 DTLS 协商过程中 可以使用证书的指纹 完成通信双方的身份校验。证书指纹在 SDP 中的描述如下 参考 SDP-Anatomy 中 DTLS 参数
a fingerprint:sha-256 49:66:12:17:0D:1C:91:AE:57:4C:C6:36:DD:D5:97:D2:7D:62:C9:9A:7F:B9:A3:F4:70:03:E7:43:91:73:23:5E密钥交换 - KeyExchange
ServerKeyExchange 用来将 Server 端使用的公钥 发送给 Client 端。分为两种情况
ClientKeyExchange 用来将 Client 使用的公钥 发送给 Server 端。
1、 RSA 算法 如果密钥协商使用的 RSA 算法 发送使用 server 端 RSA 公钥 对 premaster secret 加密发送给 server 端。
KeyExchange 的结果是 Client 和 Server 获取到了 RSA Key 或通过 DH 算法计算出共享密钥。详见 [导出 SRTP 密钥] 的过程
证书验证 - CertificateVerify使用 ClientRequest 中描述的 Hash/Signature 算法 对收到和发送的 HandShake 消息签名发送个 Server。Server 端对签名进行校验。
当 Server 和 Client 完成对称密钥的交换后 通过 ChangeCipherSpec 通知对端进入加密阶段 epoch 加 1。
随后 Client 使用交换的密钥 对 client finished 加密 使用 Finished 消息 发送给服务端。Server 使用交换的密钥 对 server finished 进行加密发送给客户端。一旦验证了 finished 消息后 就可以正常通信了。
上面介绍了 DTLS 的过程 以下通过结合上面例子给出的实际数据 详细说明 SRTP 密钥的导出步骤。
协商后的加密算法加密套件 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
椭圆曲线算法为 secp256r1 椭圆曲线的点压缩算法为 uncompressed。
椭圆曲线算法的基础知识的介绍在 ECC 椭圆曲线加密算法 - ECDH,ECDHE,ECDSA 由文档中我们可以知道 确定椭圆曲线加密算法有如下参数
定义为六元组(p,a,b,G,n,h)
通过在 SECG-SEC2 2.4.2 Recommended Parameters secp256r1 中可以查到 secp256r1 对应的参数如下
secp256r1使用的参数如下 使用的素数p: p FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF 2224(232?1) 2192 296?1 椭圆曲线E:y^2 x^3 ax b的参数定义如下 a FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC b 5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B 基点G的非压缩格式 G 046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5 有限域的阶n: n FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551 辅助因子h: h 01通过 KeyExchange 交换椭圆曲线算法公钥
ECDH Server Parameter
Pubkey:04b0ce3c5f2c4a9fbe7c2257c1328438f3378f74e9f528b6e27a00b44eee4c19e5e6b2cb6cab09f796bcf8c05102b2a4bcdc753d91cc4f431f558c845a1ba6f1ce
记为 Spk
ECDH Client Paramter
PubKey: 0454e8fbef1503109d619c39be0ccaf89efa3c3962300476465cbc66b15152cd8a900c45d506420f0123e65d8fbb70cb60b497893f81c5c2a0ef2f4bc2da996d9e
记为 Cpk
假设 Server 的使用的椭圆曲线私钥为 Ds, Client 使用的 Dc 计算共享密钥的如下 参考 ECC 椭圆曲线加密算法 - ECDH,ECDHE,ECDSA
S Ds * Cpk Dc * Spk
这个共享密钥 S 就是我们在 RFC 文档中看到的 pre-master-secret
计算 master secret计算 master secret 过程如下 可参考 Computing the Master Secret
master_secret PRF(pre_master_secret, master secret , ClientHello.random ServerHello.random)[0..47];
计算出来的 master_secret 为 48 Bytes 其中 ClientHello.random 和 ServerHello.random 在 Hello 消息中给出。PRF 是伪随机数函数 (pseudorandom function) 在协商的加密套件中给出。
使用 RFC5705 4. Exporter Definition 给出的计算方式 使用参数 master_secret, client_random, server_random 计算字节序列
key_block PRF(master_secret, EXTRACTOR-dtls_srtp , client_random server_random)[length]
在 DTLS-SRTP 4.2. Key Derivation 中描述了需要的字节序列长度。
2 * (SRTPSecurityParams.master_key_len SRTPSecurityParams.master_salt_len) bytes of data
master_key_len 和 master_salt_len 的值 在 user_srtp 描述的 profile 中定义。我们的实例中使用的 profile 为 SRTP_AES128_CM_HMAC_SHA1_80 对应的 profile 配置为
SRTP_AES128_CM_HMAC_SHA1_80 cipher: AES_128_CM cipher_key_length: 128 cipher_salt_length: 112 maximum_lifetime: 2^31 auth_function: HMAC-SHA1 auth_key_length: 160 auth_tag_length: 80
也就是我们需要 (128/8 112/8)*2 60 bytes 字节序列。
计算出 SRTP 加密参数字节序列 在 DTLS-SRTP 4.2. Key Derivation 描述了字节序列的含义
client_write_SRTP_master_key[SRTPSecurityParams.master_key_len]; // 128 bits server_write_SRTP_master_key[SRTPSecurityParams.master_key_len]; // 128 bits client_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len]; // 112 bits server_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len]; // 112 bits
至此我们得到了 Client 和 Server 使用的 SRTP 加密参数 master_key 和 master_salt.
DTLS 是基于 UDP 的 不可避免会出现丢包 需要重传。如果处理不当 会导致整个通信双方无法建立会话 通话失败。RFC6347 4.2.4 给出了超时和重传机制。
在处理重传时 以下几点需要注意
DTLS 是一个庞大的协议体系 其中包括了各种加密 签名 证书 压缩等多种算法。大多数项目是基于 OpenSSL 或 BoringSSL 实现的 DTLS 功能。在实际项目使用 OpenSSL 的 DTLS 功能 与协商有关的接口总结如下。
在开源项目 SRS 中已经支持了 WebRTC 的基础协议 对 DTLS 协议感兴趣的同学 可以基于 SRS 快速搭建本机环境 通过调试 进一步加深对 DTLS 的理解。
本文通过 WebRTC 中 SRTP 密钥的协商过程 来说明 DTLS 在 WebRTC 中的应用。DTLS 协议设计的各个加密算法的知识较多 加上 TLS 消息的在各种应用场景中的扩展 难免有理解和认知不到的地方 还需要进一步深入探索。
参考文献TLS 1.2DTLS 1.2TLS Session Hash ExtensionTCP-Based Media Transport in the Session Description ProtocolTLS ExtensionSRTP Extension for DTLS?OpenSSL ManECC 椭圆曲线加密算法 - 介绍ECC 椭圆曲线加密算法 - 有限域和离散对数ECC 椭圆曲线加密算法 - ECDH、ECDHE 和 ECDSA扫码入群和作者一起探讨音视频技术
获取更多视频云行业最新信息 ?
排查思路 无法通过远程桌面连接裸金属服务器时,我们推荐您按照以下思路排查问题...
案例背景 高校健康打卡项目发起于北京大学软件与微电子学院,是该学院张齐勋老师...
API风格说明 当前ECS服务对外开放两类风格的API: ECS服务自定义规范的API(以下...
??提到慕尼黑,大家第一个想到总是啤酒节,其实慕尼黑的文化同样闻名世界。慕尼...
客户简介 趣医网(quyiyuan.com)创立于2014年,为京颐集团重要成员企业之一,是...
云虚拟主机 可以干什么?云 虚拟主机 可以是搭 建网站 的重要产品,可用来存放网...
客户简介 全民直播是一家涵盖游戏、娱乐、户外等多领域泛娱乐的直播平台。2015年...
3月24日,腾讯发布2020年Q4及全年财报,其中金融科技及企业服务第四季收入385亿...
公司介绍 我们公司是全球法律服务整合平台,已有的4万多名律师遍布全国359个城市...
注册了 域名 不备案可以吗?可以的。 注册域名 并不是一定要备案的,只有搭 建网...