WebRTC SFU で E2EE はじめました

V
shiguredo
Published in
5 min readApr 16, 2020

最近 WebRTC SFU において E2EE を実現する技術が揃い始めてきました。そこで時雨堂でも E2EE への対応をすすめることにしました。

WebRTC SFU とは?

WebRTC は P2P をイメージすること人が多いですが、SFU はクラサバモデルの WebRTC です。

サーバが配信を代理で行うことにより、配信側の負担を減らすという仕組みです。現在、商用で WebRTC を利用する場合はほぼ WebRTC SFU を利用しています。例えば Discord や Slack 、Google Meet 、Pornhub (のライブチャット) は全て WebRTC SFU を利用しています。

ただ WebRTC SFU はサーバ側でクライアントから送られてきた暗号化された音声や映像を全て復号しています。そのためプライバシーを懸念するサービスに利用しにくいという課題があります。

E2EE とは?

E2EE は End-to-End Encryption の略で、簡単に言えばクラサバモデルの WebRTC を利用したとしても、サーバ側で音声や映像を復号することができない仕組みを提供する機能を指します。

この技術を利用しているリアルタイムビデオチャットサービスは WhatsApp や LINE 、FaceTime 、Google Duo や Wire 、Signal などです。

ただ残念ながら全て専用アプリが必要になり、ブラウザでの実現は難しかったです。特に WebRTC では不可能でした。

最近になりブラウザ側が Insertable Streams API を実装したため、WebRTC でも E2EE を実現できるようになりました。

時雨堂が提供する WebRTC SFU + E2EE

時雨堂は Sora という WebRTC SFU を提供していますが、E2EE 対応は一切 WebRTC SFU には手を入れずに実現することを目指しています。

E2EE はあくまで End の技術のため、SDK にのみ手を入れて実現します。

Sora JS SDK の拡張としての E2EE 対応

Sora JS SDK にて E2EE を有効にすることで、E2EE を利用可能です。E2EE を利用していることは Sora には知らされません。そのため、Sora は E2EE を利用しているかどうか判断できません。これこそが E2EE だと思っています。

E2EE 対応の実装は OSS にて shiguredo/sora-e2ee として公開予定です。利用時には sora-js-sdk.js とは別に sora-e2ee.js を指定して貰うことを考えています。

E2EE 実装内容

E2EE をどう実装するべきかというのはなにか決められているわけでは有りません。ただ汎用的な仕組みを使っていくべきと考えています。

  • E2EE 鍵の共有は時雨堂の範囲外とする
  • E2EE 鍵から PBKDF2 を利用し AES-GCM で利用する鍵を生成する
  • E2EE の暗号は AES-GCM 128 を利用する (256 も検討する)
  • WebCrypto を利用する
  • WebWorker を利用する
  • IV は E2EE 鍵から導いてシーケンス番号のみ共有

利用イメージ

Sora JS SDK と組み合わせて利用します。オプションに e2ee: true を渡すだけであとは何も気にする必要はありません。

ここでは E2EE 鍵は URL ハッシュから取得する仕様にしています。ハッシュ URL はサーバには共有されないのがポイントです。

<script src="./sora.js"></script>
<script src="./sora-e2ee.js"></script>
// ここでは URL ハッシュを shiguredo とする
// 以下は会議室の URL でこの URL を何かしらで共有するイメージ
// https://example.com/01E6134DRHXJEQXJMV3J19D8YR#shiguredo
var debug = false;
var secret = window.location.hash
var sora = Sora.connection('wss://example.com/signaling', debug);
var sendrecv = sora.sendrecv('Sora', '', {multistream: true, e2ee: secret});
navigator.mediaDevices.getUserMedia({audio: true, video: true})
.then(mediaStream => sendrecv.connect(mediaStream))
.then(stream => {
})
.catch(e => {
console.error(e);
});

E2EE 鍵は “shiguredo” としています。この値は SDK に渡してはいますが、WebRTC SFU には共有されません。

これだけで E2EE が実現できる仕組みを提供したいと思います。

それ以外の SDK について

Insertable Streams API が利用できないため、今すぐにはおそらく実現は難しいです。ただ将来的には対応していく予定です。

なぜ E2EE なのか

WebRTC SFU の特徴である合成などをせずに転送するというだけの機能がが E2EE を実現できています。

E2EE はクライアント側の技術でサーバに手を一切入れる必要がありません。これも魅力です。

また、WebRTC SFU Sora を利用いただいている顧客が「E2EE を提供できる」というのはとても良いことだと考えています。

リリースについて

まずは Sora Labo + Chrome Canary (flags 設定あり) で利用できるのを目指します。できるだけ早くお届けできればと思います。

--

--