SFrame

概要

SFrame は Google Duo が採用した End to End Media Encryption 用のプロトコルです。

鍵導出方式に依存しない映像や音声のフレームをの暗号化/復号をどのように処理するかについて定義されています。

SFrame は RTP パケタライゼーション前の Frame に対して処理を行います。暗号方式は AES-GCM が推奨されています。

SFrame では SFrame ヘッダーというのを新しく用意しています。このヘッダーは署名や鍵 ID 、AES-GCM の IV 用のカウンターを追加できる仕組みになっています。 Frame の Metadata を切り出すことで WebRTC SFU への影響を最小限に押さえています。

また AES-GCM の AD に SFrame ヘッダーを含めるような仕組みも入っています。 署名についてはグループ全体で 1 つの鍵を利用するような場合のみに利用し、署名自体は I フレームのみに行うべきとしています。 Signal のようなフルメッシュでそれぞれのクライアントで鍵が異なる場合は送信者の詐称ができないため署名は不要です。

これらをブラウザで Web Crypto と Web Woker 、 そして Chrome M86 で入った Insertable Streams API を利用することでクライアント側で効率よく暗号化/復号を行えるように設計されています。

Warning

Stream を Web Worker で利用するためには Chrome M87 で入る Streams API transferable streams が必要になります

ドキュメント

リファレンス実装

SFrame の著者の一人によるリファレンス実装が公開されています。 - medooze/sframe: SFrame.js pure javascript implementation based on webcrypto

Sora での利用

Sora ではフレームに Connection ID を追加しています。そのため SFrame の仕様から少しだけ逸脱しています。

  • FrameMetadta

    • WebRTC SFU Sora でコーデックのキーフレーム判定を利用するために既存フレームの先頭数バイトを残しておいています

  • SFrameHeader

    • SFrame の仕様どおりです

  • ConnectionID

    • Sora の接続を識別するための ID を追加しています

    • UUIDv4 を Clockford Base32 でエンコードしたもので 26 バイトあります

  • EncryptedFrame

    • AES-GCM 128 で暗号化したフレームです

<<FrameMetadata/binary, SFrameHeader/binary, ConnectionID:26/binary, EncryptedFrame/binary>>.

EncryptedFrame を利用する際の Associated Data に FrameMetadata と SFrameHeader と ConnectionID を含めているため、 詐称した場合は復号に失敗します。

Sora 実装

Insertable Streams

エンコード/デコード済みのフレームに対して処理を行える API があり、その部分でフレームに対する暗号処理を行います。

WebCrypto

Sora の E2EE 実装ではフレームの暗号処理に WebCrypto を利用しています。

Web Worker

Sora では Insertable Streams の処理に Web Worker を利用しています。

鍵の世代管理

SFrame で利用するための鍵の世代管理を行っています。鍵の世代管理には SFrame の KeyId を利用しています。

鍵更新タイミング

  • 誰かが参加したタイミングで自分が利用している鍵、他の人の鍵をすべて更新します

  • 誰かが離脱した 5 秒後に自分が利用している鍵を更新します

  • 誰かが離脱したタイミングで新しく鍵を生成して参加者全員に配布します

資料

SFrame

Insertable Streams API

Stream API

Streams API: transferable streams - Chrome Platform Status

© Copyright 2021, Shiguredo Inc. Created using Sphinx 4.3.1