WebRTC有什么安全性?
每个 WebRTC 连接都经过身份验证和加密。您可以确信第三方无法看到您发送的内容或插入虚假消息。您还可以确定生成会话描述的 WebRTC 代理是您正在与之通信的代理。
非常重要的一点是,没有人篡改这些信息。如果第三方在传输过程中读取会话描述,则可以。但是,WebRTC 没有防止它被修改的保护措施。攻击者可以通过更改 ICE 候选项并更新证书指纹来对您执行中间人攻击。
它是如何工作的?
WebRTC 使用两种预先存在的协议,即数据报传输层安全 (DTLS) 和安全实时传输协议 (SRTP)。
DTLS 允许您协商会话,然后在两个对等体之间安全地交换数据。它是 TLS 的兄弟,TLS 与支持 HTTPS 的技术相同,但 DTLS 使用 UDP 而不是 TCP 作为传输层。这意味着协议必须处理不可靠的交付。SRTP 专为安全地交换介质而设计。我们可以使用它而不是 DTLS 进行一些优化。
首先使用 DTLS。它通过 ICE 提供的连接进行握手。DTLS 是客户端/服务器协议,因此需要一端开始握手。客户端/服务器角色是在信令期间选择的。在 DTLS 握手期间,双方都会提供证书。 握手完成后,此证书将与会话描述中的证书哈希进行比较。这是为了确保握手发生在您期望的 WebRTC 代理上。然后,DTLS 连接可用于 DataChannel 通信。
为了创建 SRTP 会话,我们使用 DTLS 生成的密钥对其进行初始化。SRTP 没有握手机制,因此必须使用外部键进行引导。完成此操作后,可以交换使用 SRTP 加密的介质!
安全 101
要了解本章中介绍的技术,您需要先了解这些术语。密码学是一个棘手的主题,因此也值得咨询其他来源!
明文和密文
明文是密码的输入。密文是密码的输出。
密码
密码是将明文转换为密文的一系列步骤。然后可以反转密码,因此您可以将密文恢复为明文。密码通常有一个密钥来改变其行为。另一个术语是加密和解密。
一个简单的密码是 ROT13。每个字母向前移动 13 个字符。要撤消密码,请向后移动 13 个字符。明文HELLO
将成为密文URYYB
。在本例中,密码为 ROT,密钥为 13。
哈希函数
加密哈希函数是生成摘要的单向过程。给定一个输入,它每次都会生成相同的输出。重要的是输出不可逆。如果有输出,则无法确定其输入。当您想要确认消息未被篡改时,哈希非常有用。
一个简单的(虽然肯定不适合真正的密码学)哈希函数是只取每隔一个字母。HELLO
会变成HLO
.您不能假设HELLO
是输入,但您可以确认HELLO
这将是与哈希摘要的匹配。
公钥/私钥加密
公钥/私钥加密描述了 DTLS 和 SRTP 使用的密码类型。在这个系统中,你有两个密钥,一个公钥和私钥。公钥用于加密消息,可以安全共享。 私钥用于解密,不应共享。它是唯一可以解密使用公钥加密的消息的密钥。
Diffie-Hellman 交换
Diffie-Hellman 交换允许两个从未见过面的用户通过 Internet 安全地创建共享密钥。用户A可以向用户B发送机密,而不必担心被窃听。这取决于破解离散对数问题的难度。 您不需要完全了解其工作原理,但了解这就是使 DTLS 握手成为可能的原因会有所帮助。
伪随机函数
伪随机函数 (PRF) 是一个预定义的函数,用于生成看似随机的值。它可能需要多个输入并生成单个输出。
键导函数
密钥推导是一种伪随机函数。密钥派生是用于使密钥更强的函数。一种常见的模式是关键拉伸。
假设您获得了一个 8 字节的密钥。您可以使用 KDF 使其更强大。
随机数
随机数是密码的附加输入。这是为了从密码中获取不同的输出,即使您多次加密同一消息也是如此。
如果对同一消息加密 10 次,密码将为您提供相同的密文 10 次。通过使用随机数,您可以获得不同的输出,同时仍然使用相同的键。为每条消息使用不同的随机数很重要!否则,它否定了大部分价值。
消息验证码
消息身份验证代码是放置在消息末尾的哈希值。MAC 证明消息来自您预期的用户。
如果不使用 MAC,攻击者可能会插入无效消息。解密后,你只会有垃圾,因为他们不知道密钥。
密钥轮换
密钥轮换是按时间间隔更改密钥的做法。这使得被盗密钥的影响较小。如果密钥被盗或泄露,可以解密的数据就会减少。
DTLS系列
DTLS(数据报传输层安全性)允许两个对等体在没有预先存在的配置的情况下建立安全通信。即使有人窃听对话,他们也无法解密消息。
要使 DTLS 客户端和服务器进行通信,它们需要就密码和密钥达成一致。它们通过执行 DTLS 握手来确定这些值。在握手期间,消息是纯文本的。 当 DTLS 客户端/服务器交换了足够多的详细信息以开始加密时,它会发送 Change Cipher Spec
.此消息之后,后续的每条消息都将被加密!
数据包格式
每个 DTLS 数据包都以标头开头。
Content Type内容类型
您可以期待以下类型:
20
- 更改密码规范22
-握手23
- 应用数据
Handshake
用于交换详细信息以启动会话。 用于通知对方一切都将被加密。 是加密的消息。Change Cipher Spec
Application Data
Version 版本
版本可以是 (DTLS v1.0) 或 (DTLS v1.2),没有 v1.1。0x0000feff
0x0000fefd
Epoch时代
纪元从 开始,但在 之后变为 。任何具有非零纪元的消息都将加密。0
1
Change Cipher Spec
Sequence Number序列号
序列号用于使消息井然有序。每条消息都会增加序列号。当纪元递增时,序列号将重新开始。
Length and Payload长度和有效载荷
有效负载是特定的。对于加密数据。因为它会根据消息而有所不同。长度是多大。Content Type
Application Data
Payload
Handshake
Payload
握手状态机
在握手期间,客户端/服务器交换一系列消息。这些消息按外部测试版分组。每个航班中可能包含多条消息(或只有一条消息)。 在收到外部测试版中的所有消息之前,外部测试版不会完成。我们将在下面更详细地描述每条消息的目的。
ClientHello
ClientHello 是客户端发送的初始消息。它包含属性列表。这些属性告诉服务器客户端支持的密码和功能。对于 WebRTC,这也是我们选择 SRTP 密码的方式。它还包含将用于生成会话密钥的随机数据。
HelloVerifyRequest
HelloVerifyRequest 由服务器发送到客户端。这是为了确保客户端打算发送请求。然后,客户端重新发送 ClientHello,但使用 HelloVerifyRequest 中提供的令牌。
ServerHello
ServerHello 是服务器对此会话配置的响应。它包含此会话结束时将使用的密码。它还包含服务器随机数据。
Certificate
Certificate包含客户端或服务器的证书。这用于唯一标识我们正在与谁通信。握手结束后,我们将确保此证书在哈希处理时与 .SessionDescription
ServerKeyExchange/ClientKeyExchange#
这些消息用于传输公钥。启动时,客户端和服务器都会生成一个密钥对。握手后,这些值将用于生成 .Pre-Master Secret
CertificateRequest
服务器发送 CertificateRequest,通知客户端它需要证书。服务器可以请求或要求证书。
ServerHelloDone
ServerHelloDone 通知客户端服务器已完成握手。
CertificateVerify
CertificateVerify 是发件人证明其具有在证书消息中发送的私钥的方式。
ChangeCipherSpec
ChangeCipherSpec 通知接收方,在此消息之后发送的所有内容都将被加密。
Finished
Finished 已加密,包含所有消息的哈希值。这是为了断言握手没有被篡改。
密钥生成
握手完成后,您可以开始发送加密数据。密码由服务器选择,位于 ServerHello 中。但是,钥匙是如何选择的呢?
首先,我们生成 Pre-Master Secret
.为了获得此值,对 ServerKeyExchange
和ClientKeyExchange
交换的键使用 Diffie–Hellman。详细信息因所选密码而异。
接下来生成Master Secret
。每个版本的 DTLS 都有一个定义的Pseudorandom function
.对于 DTLS 1.2,该函数采用Pre-Master Secret
ClientHello
和ServerHello
中的随机值。 Pseudorandom Function
运行 的输出是Master Secret
.Master Secret
是用于密码的值。
交换 ApplicationData
DTLS 的主力是ApplicationData
.现在我们有了一个初始化的密码,我们可以开始加密和发送值了。
ApplicationData
如前所述,邮件使用 DTLS 标头。用密文填充Payload
。现在,您拥有了一个正常工作的 DTLS 会话,并且可以安全地进行通信。
DTLS 具有更多有趣的功能,例如重新协商。WebRTC 不使用它们,因此此处不介绍它们。
SRTP系列
SRTP 是专门为加密 RTP 数据包而设计的协议。要启动 SRTP 会话,请指定密钥和密码。与 DTLS 不同,它没有握手机制。所有配置和密钥都是在 DTLS 握手期间生成的。
DTLS 提供了一个专用的 API,用于导出要由其他进程使用的密钥。这在 RFC 5705 中定义。
会话创建
SRTP 定义了用于输入的密钥派生函数。在创建 SRTP 会话时,输入将通过它运行,以生成 SRTP 密码的密钥。在此之后,您可以继续处理介质。
交换媒体
每个 RTP 数据包都有一个 16 位 SequenceNumber。这些序列号用于保持数据包的顺序,如主键。在通话期间,这些将滚动。SRTP 会跟踪它,并将其称为翻转计数器。
加密数据包时,SRTP 使用滚动更新计数器和序列号作为随机数。这是为了确保即使两次发送相同的数据,密文也会有所不同。这对于防止攻击者识别模式或尝试重放攻击非常重要。