しくみ

Crocodile はどうやって会話をあなたのものに保つのか

アーキテクチャとプロトコルをわかりやすく紹介します。各章はまず考え方から始まります。技術的な詳細は「技術的な詳細」を開いてください。

章 1

4種類の登場人物

Crocodile は役割を分担しています。あなたの言葉を見られるのは話している相手だけで、知らない人が運用する部分には決して見えません。

あなたのアプリ

あなたの鍵を保管し、送るものすべてを暗号化し、受け取るものを復号します。メッセージ履歴はここにあり、ほかのどこにもありません。

知っていること: あなたが送受信するすべて。それはあなたのものです。

ホスト

ボイスルームやスペースごとに、あるメンバーのアプリが選ばれ、暗号化された通信をほかのメンバーに中継します。ほかの人と同じ、ひとりのメンバーです。

知っていること: メンバーの IP アドレスと誰が話しているか。何を話しているかは決して知りません。

調整サーバー

ボランティアが運用する電話交換台です。プロフィールとスペースを保存し、誰がオンラインかを伝え、ホストを選びます。ひとつのネットワークにつながっています。

知っていること: プロフィール、メンバーシップ、誰がオンラインか。何を話しているかは決して知りません。

ディレクトリ

調整サーバーの電話帳で、新しいアプリがどこから始めればよいかわかるようにします。人については何も知りません。

知っていること: サーバーの一覧だけ。

章 2

アカウントはパスワードではなく鍵

Crocodile をインストールすると、アプリがパソコン上で32バイトのランダムな秘密を生成します。そこから2つの鍵が生まれます。ひとつは公開するものに署名するため、もうひとつは暗号化されたメッセージを受け取るためのものです。ユーザー ID は署名鍵のフィンガープリントです。

ID は鍵から計算されるので、サーバーが別の鍵にすり替えてあなたになりすますことはできません。盗まれるパスワードも、サポート担当者をだまして行わせるリセットもありません。秘密はリカバリーキーとして一度だけ表示され、システムのキーチェーンで暗号化されてデバイス上に保管されます。

技術的な詳細
  • 32バイトのシードから、Ed25519 署名鍵と X25519 暗号鍵を導出します。ユーザー ID は base32(SHA-256(署名公開鍵)) の先頭26文字です。
  • 各デバイスは署名付きのデバイスレコードを公開し、毎週ローテーションするプレキーバンドル(X25519 + ML-KEM-768)を添えます。古いプレキーの秘密は猶予期間の後に削除されます。
  • セキュリティ番号を使えば、ほかの安全なメッセンジャーと同様に、二人が別の経路で鍵を照合できます。
  • ローカルデータ(アイデンティティ、プレキー、履歴)は、OS のキーチェーンで保護された鍵で暗号化して保存されます。

章 3

最速のサーバーを見つける

アプリはディレクトリから調整サーバーの一覧をダウンロードし、それぞれの応答速度を測って、最も速いサーバーに接続します。2番目は待機していて、サーバーが落ちるとアプリはすぐに切り替えます。

まず最初に、サーバーが自分の身元を証明し、アプリとサーバーがその接続用の鍵を取り決めます。以降は、やり取りするメタデータでさえ HTTPS の上でさらに暗号化されるため、自宅のサーバーでも安全に運用できます。

技術的な詳細
  • ディレクトリは各サーバーを、そのサーバー自身の署名付き、アドレスを伏せた形で掲載します。アプリはエントリを使う前に署名を検証します。
  • サーバーの署名付きハローには、新しいハイブリッド鍵交換の提案(X25519 + ML-KEM-768)が含まれます。アプリはディレクトリの鍵でそれを検証し、応答して、やり取りの記録全体に署名します。以降のすべてのフレームは AES-256-GCM で暗号化され、パディングされます。
  • サーバーは2つのポートで STUN にも応答するため、アプリは Google や Cloudflare に問い合わせることなく、自分のパブリックアドレスと NAT の種類を知ることができます。

章 4

あなたについて嘘をつけないサーバー

あなたのプロフィール、作成したスペース、その招待、メンバーの一覧は、書いた人が署名した小さなレコードです。サーバーはそれらを保存して共有し、すべてのサーバーとすべてのアプリが署名を検証します。サーバーはレコードの中継を拒否することはできても、改ざんしたり捏造したりすることはできません。

調整サーバーは互いを見つけてネットワークを形成します。各レコードはハッシュで選ばれた複数のサーバーに保持され、それらが変更を互いにコピーするので、どのサーバーが落ちてもネットワークは動き続けます。

技術的な詳細
  • レコードの種類:プロフィール、封印されたフレンドリスト、スペース、招待、メンバー、デバイス、ノート。それぞれ書き込みを許された作成者がいて、検証(署名、権限、「最後の書き込みが勝つ」バージョン)はサーバーとクライアントで同一です。
  • フレンドリストは所有者のデバイスだけに向けて暗号化され、フレンドリクエストは送信者を明かさない封印されたノートとして届くため、サーバーは誰と誰が友だちなのかを知りません。
  • 各レコードは、そのシャードのコンシステントハッシュリング上の先頭数台のサーバーが担当します。担当サーバーは書き込みを複製し、シーケンスカーソルで欠けた分を取り込み、サーバーの参加・離脱に応じてレコードを引き継ぎます。

章 5

友だちがホストし、バックアップが控える

人がボイスルームに参加したりスペースを開いたりすると、調整サーバーは全員の接続状況(ネットワークの開放度、アップロード速度、パソコン、バッテリー駆動かどうか)を見て、最適なメンバーをホストに選びます。次点がバックアップです。

全員がホストのアプリに接続し、ホストが暗号化された音声を中継します。負荷を軽くするため、各リスナーには声の大きい数人の話者だけを送ります。音声は途中で平文になることはなく、ホストは封をされたパケットを運ぶだけです。

ホストが抜けたり到達できなくなったりすると、バックアップが引き継ぎ、全員がそちらに再接続します。たいていは誰も気づきません。

技術的な詳細
  • ホストはアプリ内で小さな SFU(selective forwarding unit)を動かします。各メンバーはそれに対して WebRTC 接続をひとつ開き、上り音声トラック1本、下りの話者スロット5つ、データチャンネル1本を使います。
  • 話者スロットは RFC 6464 の音声レベルヘッダー(“last-N”)で割り当てられ、シーケンス番号を書き換えることで、各スロットが途切れないひとつのストリームに保たれます。
  • オファーとアンサーは、セッション、エポック、双方の ID、DTLS フィンガープリントを対象にアイデンティティ鍵で署名されるため、調整サーバーが間に割り込むことはできません。
  • ホストが替わるたびにエポック番号が上がり、古いオファーは無視されます。ホストに到達できないメンバーはそれを報告し、半数が同意するとバックアップが引き継ぎます。

章 6

何層にも重なる暗号化

すべてはデバイスを出る前に暗号化され、鍵を持っているのは会話に参加している人だけです。メッセージが届くまでに何が起きるかを見てみましょう。

ひとつのメッセージ、4つの層

アプリはメッセージに署名して、あなたから来たことを他の人が証明できるようにし、長さから何もわからないようパディングし、会話のメンバーだけが持つ鍵で暗号化し、それ自体も暗号化された接続で送ります。途中に誰がいても、見えるのは標準サイズの意味のないバイト列だけです。

量子コンピューターへの備え

鍵は、実績のある従来方式 X25519 と、新しいポスト量子標準 ML-KEM-768 のハイブリッドで交換されます。攻撃者は両方を破らなければなりません。今日暗号化された通信を記録しておき、量子コンピューターで解読できる日を待つ、ということもありうるので、これは重要です。

前に進み続ける鍵

各メンバーの鍵はラチェットのように回ります。メッセージを送るたびに、前にしか進まないチェーンの次の鍵に置き換えられ、古い鍵は削除されます。今日鍵を盗んだ人でも、昨日のメッセージは読めません。30分ごと、そして誰かが抜けるたびに、全員が新しいランダムな鍵で新しいチェーンを始めるので、盗まれた鍵もすぐに役に立たなくなります。

音声をフレームごとに

あなたの声は1秒あたり約50の小さなフレームに分けられ、マイクの直後、ネットワークに届く前に暗号化されます。暗号化できなかったフレームは破棄され、平文で送られることはありません。音声は固定ビットレートを使うので、パケットのサイズから話の内容がわかることはありません。

技術的な詳細
  • ペアワイズの秘密(送信者鍵の配布、履歴の同期、デバイスのリンク、サーバーチャンネル)は、X25519 と ML-KEM-768(FIPS 203)を HKDF-SHA256 で組み合わせます。
  • 送信者鍵には2本の HKDF チェーンがあります。テキストのチェーンはメッセージごとに、音声のチェーンは30秒ごとに進みます。鍵は30分ごとと、誰かが抜けたときに交換され、アプリが署名付きレコードから自らメンバーシップを確認したデバイスにだけ送られます。
  • 音声:Encoded Transform ワーカーが、各 Opus フレームを AES-256-GCM で暗号化し、認証付きの SFrame 風サフィックス(鍵 ID、世代、カウンター)を付けます。
  • テキスト:作成者が署名(Ed25519)し、Padmé でパディングし、テキストのチェーンで暗号化します。
  • デバイスに送る封印ボックスは、そのデバイスの現在のプレキーを使い、送信者が署名するため、オフラインのデバイスに送られたメッセージでも前方秘匿性が得られます。

章 7

直接つながれないとき

オフィスや大学の厳しいファイアウォールなど、一部のネットワークはパソコン同士の直接接続をブロックします。そうなったとき Crocodile はそれを知らせ、調整サーバーに通信を中継させることを許可できます。

リレーは、すでにエンドツーエンド暗号化されたパケットを転送します。見えるのはサイズとタイミングだけで、中身は見えません。許可は1回につき1時間で、まだ必要な場合にだけ更新されます。

技術的な詳細
  • リレーは標準の TURN(RFC 5766)で、調整サーバーの UDP ポート上で短期間の認証情報を使って動作します。サーバーは利用できる人数を制限します。
  • 接続時、アプリは2つの STUN ポートに対して自分のネットワークをテストし、オープン、制限あり(シンメトリック NAT)、ブロックのいずれかに分類して、必要ならリレーを提案します。
  • 各接続は4つのステップ(オファー、アンサー、ネットワーク経路、暗号化チャンネル)を記録するので、何かが失敗したとき、アプリはどこで失敗したかを示せます。

章 8

必ず届くメッセージ

どのサーバーも履歴を保持しないので、Crocodile のアプリ同士がメッセージを受け渡します。オフラインの人にメッセージを送ると、こうなります。

  1. あなたの手元で待機

    メッセージはアプリの送信トレイに入り、小さな時計が表示されます。

  2. 友だちがオンラインに

    二人ともオンラインになった瞬間、アプリが相手のデバイス向けに封をしたメッセージを届けます。

  3. 確認済み

    相手のアプリが受信を確認し、時計が消えます。スペースでは、メッセージを見逃したメンバーがホストとバックアップから取り込みます。

  4. またはメールボックス

    希望すれば、サーバーがダイレクトメッセージを最大7日間、デバイスごとに封をした状態で(サーバー自身には読めません)保管し、配信後に削除します。

章 9

パソコンを追加する

新しいパソコンに短いコードが表示されます。それをサインイン済みのパソコンに入力し、両方の画面に同じ6桁のセキュリティコードが表示されることを確認します。一致すれば、アカウントが暗号化されて転送され、新しいデバイスの準備が整います。

セキュリティコードは両方のデバイスの鍵をカバーしているので、途中で誰かがどちらかをすり替えようとすれば、コードが一致せず気づくことができます。

用語集

セキュリティ関連の記事でよく見かける用語を、それぞれ1〜2文で。

エンドツーエンド暗号化
鍵を持っているのは送信者と受信者だけです。サーバーを含め、途中でメッセージを運ぶものには意味のないデータしか見えません。
ピアツーピア
アプリが中央のサーバーではなく、互いに直接接続すること。
ポスト量子暗号
現在のインターネットの大部分が使っている方式を破りうる、将来の量子コンピューターに耐えるよう設計された暗号。ML-KEM は NIST が2024年に公開した標準です。
前方秘匿性
今日鍵が盗まれても、古いメッセージは開けません。そのときに使った鍵はすでに削除されているからです。
侵害後の安全性
鍵が盗まれた後でも、新しいランダムな鍵によって盗んだ人はすぐに再び締め出されます。Crocodile では30分以内、または誰かが抜けた時点ですぐに起こります。
デジタル署名
秘密鍵で作る数学的な印章。誰でも公開鍵で検証でき、秘密鍵を持たない人には偽造できません。
NAT、STUN、TURN
家庭用ルーターはパソコンをひとつのパブリックアドレスの裏に隠します(NAT)。STUN はアプリが直接接続できるよう自分のパブリックアドレスを知る手助けをし、TURN はそれができないときに通信を中継します。
SFU
selective forwarding unit(選択的転送ユニット)。各話者の音声を、ミックスも復号もせずに各リスナーへ転送します。Crocodile ではホストのアプリ内で動作します。
メタデータ
会話の中身ではなく、会話に関するデータ:誰が誰と、いつ、どれくらいやり取りしたか。Crocodile は中身を完全に暗号化し、メタデータを減らしていますが、サーバーにはその一部が見えます。

アーキテクチャ文書の全文を読む(英語)