tosstome のしくみ
最終確認
tosstome は、Cloudflare Workers 上の小さなサービスとウェブページでできています。サーバーは端末どうしを引き合わせ、どうしても必要なときだけデータを中継します。ファイルを保存することはありません。
1. お互いを見つける
ページを開くと、ブラウザは WebSocket でサーバーに接続します。同じグローバル IP アドレスから接続してきた端末は、たいていは同じ家庭やオフィスのネットワークにいるものとして同じグループに入れられ、お互いの「同じネットワーク」の一覧に表示されます。アドレスは使う前にハッシュ化されます。別のネットワークにいる端末どうしは、6 桁のコードで、その場限りの専用グループに入ります。
2. 直接つながる
端末をタップすると、2 台はサーバー経由で WebRTC の接続情報を交換し、直接のデータチャネルを開こうとします。家庭用ルーターの先にある相手にどうやって届くかは、Cloudflare の STUN サービスで調べます。WebRTC の直接チャネルは、ブラウザによってエンドツーエンドで暗号化されます (DTLS)。
3. 中継サーバーに切り替える
ネットワークによっては直接接続が遮断されます。企業のファイアウォール、ゲスト Wi-Fi、キャリアグレード NAT のモバイル回線などです。数秒以内に直接チャネルが成立しなければ、両側とも代わりに Cloudflare 上の中継サーバーに接続します。中継サーバーは各チャンクを届いた順に転送し、何も保存しません。中継サーバーとの通信は TLS で暗号化されますが、中継経路はまだエンドツーエンドでは暗号化されていません。これは今後の予定に入っています。
4. データを運ぶ
ブラウザでもコマンドラインツールでも、同じ転送プロトコルが動きます。小さな JSON の制御メッセージとバイナリのチャンクを使い、受信側が確認応答を返すので、送信側が遅い回線に大量のデータを押し込むことはありません。直接チャネルでも中継サーバーでも、動作は同じです。
5. 受信箱
コマンドラインツールは、常時稼働の受信箱を保持します。ここでは 2 つの秘密のキーを作ります。コンピューターの中にとどまるエージェントキーと、受信箱のリンクの # の後ろに入る送信キーです。ブラウザはリンクのこの部分をサーバーに送らず、キーは WebSocket の中で渡されます。サーバーが保持するのは、両方のキーの SHA-256 ハッシュだけです。スマートフォンがリンクを開いて送信すると、サーバーは 2 つのブラウザの間と同じように、スマートフォンとコンピューターの間で WebRTC の接続情報を受け渡します。そのため同じネットワークなら、ファイルはネットワークの外に出ず、そのまま受信箱のフォルダーに届きます。直接チャネルが成立しない場合は、両側が代わりに中継セッションを使います。コマンドラインツールは、6 桁のコードでブラウザに送るときや、ブラウザが「同じネットワーク」の一覧から送ってくるときにも、同じ方法で直接接続します。
まだ実装していないこと
- 中継経路でのエンドツーエンド暗号化
- ブラウザでの、署名付きで永続的な端末ペアリング
- 受信箱キーの入力ミスに対するロール別ロックアウト以外のレート制限
サービスが何を把握しているかは、プライバシーのページをお読みください。
よくある質問
tosstome はエンドツーエンドで暗号化されていますか?
WebRTC の直接転送は、ブラウザの DTLS によってエンドツーエンドで暗号化されています。中継サーバーを通る転送は、各端末と Cloudflare の間で TLS により暗号化されますが、まだエンドツーエンドではありません。
WebRTC とは何ですか?
ブラウザの標準規格で、リアルタイムのピアツーピア接続を実現します。ビデオ通話アプリなどで使われています。tosstome は、そのデータチャネルを使ってブラウザ間で直接ファイルを送ります。
ファイルはどこかにアップロードされたり、保存されたりしますか?
いいえ。ネットワークの条件が合えば、ファイルは WebRTC で端末から端末へ直接届きます。合わない場合は Cloudflare 上の中継サーバーを通りますが、届いたバイトをそのまま転送するだけで、何も保存しません。受信側がオフラインなら、何も送信されません。
ピアツーピアなのに、なぜインターネットが必要ですか?
ブラウザどうしがお互いを見つけて接続情報を交換するために、サーバーが必要だからです。直接つながったあとは、ファイルのデータは端末の間だけを流れます。