有奖小调查

3 分钟回答 几 个小问题,让内容更符合你的 WebRTC 学习与开发期望。
每个月最后一天会随机抽出 5 名获奖者,并通过邮件联系送上奖品。
填写问卷

使用WebRTC Insertable Stream实现端对端加密(一)

几周前,Chrome团队宣布有意进行有关API在blink-dev list中的实验,使其用WebRTC自定义处理。该通告附有Harald Alvestrand编写的解释器文档,该文档显示了API的基本用法。正如我在上一篇文章中提到的那样,这也许能够帮助我们把中间系统方案中的端到端加密(e2ee)添加到WebRTC中。

出于好奇,当jitsi.org的前webrtcHacks客座作者Emil Ivov着手讨论关于开展协作,研究API具体有何功能时,我始终密切关注着他的实现进度。具体来说,我们想看看WebRTC Insertable Stream是否可以解决用户无法控制的中间系统设备(如用于媒体路由的选择性转发单元(SFU))的端到端加密问题。

似乎是可以的!请继续阅读以获取更多细节。

使用WebRTC Insertable Stream API加密的两个端之间发送的端到端加密(e2ee)媒体流的中间系统视图。

在阐述此项目之前,首先我们该回顾一下媒体加密如何与SFU之类的媒体服务器设备一起工作。

WebRTC中的媒体加密

WebRTC授权加密。它使用DTLS-SRTP来加密媒体。DTLS-SRTP通过使用DTLS握手,导出用于加密RTP数据包有效载荷的密钥来工作。而通过比较通过信令服务器交换的SDP中的a =指纹行与握手中使用的自签名证书的指纹,DTLS-SRTP可以进行进行身份验证。这可以称为端到端加密,因为协商的密钥不会离开本地设备,并且浏览器无法访问它们。但是,如果不进行身份验证,DTLS-SRTP仍然容易受到中间人攻击

想获取更多有关加密以及WebRTC如何发扬光大的更多背景信息,请参阅我们有关强制使用DTLS的帖子,

SFU挑战

多方的主要结构是选择性转发单元(SFU)。SFU其实是一个分组路由器,可以将一个或少量流从一个用户转发到许多其他用户。想了解更详细的解释,请查看这篇文章

在加密方面,DTLS-SRTP协商在每个对等端与SFU之间进行。这意味着SFU可以访问未加密的有效负载,也可以侦听。这对于服务器端记录等功能是必需的。不利的一面是,你需要信任运行SFU和/或客户端代码的实体,以使该流保持私有。零信任永远是隐私的最佳选择。

与更传统的用于解码和混合媒体的VoIP多点控制单元(MCU)不同,SFU仅路由数据包。其重点并不在内容上(除了标头中的字节数以及帧是否为关键帧)。所以,从理论上讲,SFU不需要解码和解密任何内容。自WebRTC成立以来,SFU开发人员就已经意识到了这一问题。同样,从很久以前开始,Google的webrtc.org库就也采用了“帧加密”方法,这可能是为Google Duo添加的,但并不存在浏览器中。然而,目前公认的,解决此问题的“正确” API需要WebRTC Insertable Stream的辅助。

生效

我们最初的游戏计划如下所示:

  1. 生效;

端到端加密示例

幸运的是,由于Harald Alvestrand一直致力于开发一个可以大大简化我们工作的样本,所以使项目生效会容易一些。样本中采用的方法很好的证明了这一点:

  1. 打开两个连接;
  2. 在两者上都应用(故意弱化,用密钥对内容进行异或)加密,但是;
  3. 仅解密其中之一。

你可以在此处测试样本。确保你运行的是最新的Chrome Canary(84.0.4112.0或更高版本),并且确保已启用实验性的“ Web平台功能”标志。

该API非常易于使用。一个简单的记录转换函数如下所示:

const sender = pc1.addTrack(stream.getVideoTracks()[0], stream);
const senderStreams = sender.createEncodedVideoStreams() :
const senderTransformStream = new TransformStream({
    transform: (chunk, controller) {
      console.log(chunk, chunk.data.byteLength);
      controller.enqueue(chunk);
    }
  });
senderStreams.readableStream
  .pipeThrough(senderTransformStream)
  .pipeTo(senderStreams.writableStream);

之后为每个视频帧调用转换函数。 包括一个编码的帧对象(命名为“块”)和一个控制器对象。控制器对象提供了一种方法,能将修改后的帧传递到下一步。在我们的例子中,这是由上面的pipeTo调用定义的,是打包程序。

文章地址:https://webrtchacks.com/true-end-to-end-encryption-with-webrtc-insertable-streams/

原文作者:Philipp Hancke

 

填写常用邮箱,接收社区更新

WebRTC 中文社区由

运营