このページは情報提供を目的としたものです。実装にあたってこの知識は必要ありません(Chat XDK がここに書かれた全ての処理を代わりに実行します)。
全体像
アカウント作成からメッセージの送受信までのフロー全体を見てみましょう。1
アカウント作成
ここで Chat XDK は、あなたのデバイス上で 2 組のキーペアを生成します。
- identity キーペア — シークレットを受け取るためのもの
- signing キーペア — 作者であることを証明するためのもの
2
会話の作成
あなたにメッセージを送るには、送信者は新しい会話鍵(メッセージを暗号化する対称鍵)を生成します。送信者は X バックエンドからあなたの公開鍵を取得し、その署名を検証し、あなたの identity 鍵に対して会話鍵を暗号化します。これは公開鍵暗号の重要な特性です。誰でもあなたの公開鍵に対して暗号化できますが、復号できるのはあなたの秘密鍵だけであり、それを持っているのはあなただけです。したがって X は暗号化されたコピーを保存・配信することはできますが、それを開くことはできません。(使用されている具体的な方式については glossary を参照してください。)なぜメッセージを直接あなたの公開鍵で暗号化しないのでしょうか? 速度のためです。公開鍵暗号は対称鍵暗号よりもはるかにコストが高いため、鍵を交換することで、以降のメッセージをより効率的に扱えるようになります。
3
メッセージング
誰かがあなたにメッセージを送ると、あなたの identity 公開鍵で暗号化された会話鍵と、その会話鍵で暗号化されたメッセージを受け取ります。あなたは identity 秘密鍵を使って会話鍵を復号し(繰り返しますが、この鍵を持っているのはあなただけです)、得られた会話鍵を使ってメッセージを復号します。会話における鍵は、さまざまな理由で時折ローテーションされます(新しい対称鍵が共有されます)。そのため、参加者が常に正しい鍵を使っていることを確認できるように、各会話鍵にはバージョンが付いています。
4
署名
暗号化により、誰でもあなたにメッセージを送ることができ、それを復号できるのはあなただけになります。署名はある意味その反対で、あなた(だけ)がメッセージに署名でき、誰でもその署名を検証できます。実際には、署名には秘密鍵が必要で、検証には公開鍵が使えます。X Chat では、送信者は全員自分のメッセージに署名します。署名は、誰がメッセージに署名したかと、署名された正確なバイト列の両方を証明するため、すべての受信者はこのメッセージが送信者の入力そのものであることを検証できます。ここでも XDK があなたの代わりにこれを処理します。詳細は Signatures explained で扱います。
まとめると
X Chat は 3 つの標準的な暗号ツールを組み合わせており、それぞれが得意な仕事を 1 つだけ担っています。- 会話鍵はメッセージを暗号化します。対称鍵で、すべてのメッセージやメディア通信に対して十分に高速です。
- identity キーペアは、他の誰か(X を含む)に見られることなく、各参加者に会話鍵を届けます。
- signing キーペアは作者であることを証明します。すべてのメッセージには、受信者が検証する署名が付いています。
実例で見てみよう
Bob と Carol とグループを作成する際に、実際に何が起きるのかを追ってみましょう。1
会話鍵を生成する
XDK は新しいランダムな会話鍵を生成します。この時点では、鍵はあなたのデバイスのメモリ上にしか存在しません。
2
参加者の鍵を取得して検証する
あなたのアプリは、X バックエンドから Bob と Carol の公開鍵を取得し、それぞれの署名を検証します。署名が正しくない場合は処理を中止します。検証できなかった鍵に対して暗号化してはいけません。
3
各参加者に対して鍵をラップする
XDK は会話鍵を 3 回ラップします。Bob の identity 公開鍵、Carol のそれ、そしてあなた自身のもの(あなたの他のデバイスからも読めるように)に対してです。
4
変更に署名する
XDK は、まさにこの変更を記述するペイロードに署名します。グループ、そのメンバー、ラップされた鍵などです。グループの作成には2 つの action signature が必要ですが、XDK があなたの代わりに両方を生成します。
5
公開する
あなたのアプリは、ラップされたコピーと署名を X に POST します。サーバーは自分では開けない 3 つの暗号化された blob を保存します。生の会話鍵があなたのデバイスから出ることは一度もありません!
6
Bob が読む
Bob の XDK は、自身の identity 秘密鍵で自分のコピーをアンラップし、鍵の変更があなたから来たものであることを検証し、生の会話鍵を保持します。
Secure key backup: 分散型鍵ストレージ
先ほど、あなたの秘密鍵は secure key backup に保存され、あなたのパスコードによってのみ復元可能だと述べました。これは人々が最も懐疑的に感じる部分なので、その仕組みを見てみましょう。X が読めない状態で、どうやって鍵をバックアップできるのでしょうか?従来の鍵ストレージの問題
Secure key backup による解決方法
X Chat はオープンソースの Juicebox プロトコルを使用しており、これはしきい値秘密分散とパスコード保護を組み合わせたものです。プロトコルの完全な仕様はそちらにありますが、簡潔にまとめると次のようになります。 保存(アカウント作成時、1 回のみ)。 XDK はあなたの秘密鍵をシェアに分割し、互いに隔離された 3 つの realm(サービス)に分散します。3 つとも X が運用しているため、隔離だけでは大した意味を持ちません。ここでハードウェアが登場します。3 つのうち 2 つの realm はハードウェアセキュリティモジュール(HSM)の内部に置かれています。HSM は耐タンパー性のあるハードウェアで、サーバへのフルアクセスを持つ X の管理者に対してすら、自分のシェアを渡しません。1 つのシェアだけでは何もわからず、復元には 3 つのうち 2 つの realm のシェアが必要となるため、あらゆる復元の経路は必ず少なくとも 1 つの HSM を経由します。つまり、鍵に至るソフトウェアだけの経路は存在しません。HSM のソフトウェアと、それをプロビジョニングした鍵セレモニーは公に文書化されています。 復元(新しいデバイス)。 あなたはパスコードを入力し、XDK は各 realm に対してあなたがそれを知っていることを証明します。Juicebox プロトコルにより、パスコードがあなたのデバイスから出ることなくこれが可能になります。あなたを検証した各 realm は鍵のシェアを解放し、3 つのうち 2 つが応答した時点で、XDK はあなたのデバイス上で鍵を再構成します。 推測回数の制限。 各 realm は、パスコードの誤入力を最大 20 回まで許容します。20 回目に失敗すると、あなたの鍵のシェアはその realm から削除されます。これは HSM によってハードウェアで強制され、あらゆる総当たり攻撃から保護します。 その結果、あなたはパスコードだけで新しいデバイスに鍵を復元でき、単一の realm が秘密全体を保持することは決してなく、ハードウェアに支えられた realm は X 自身に対してすらその制限を強制します。これらは手動で設定する必要はありません。Chat XDK にはバックアップクライアントが含まれており、realm 設定はあなたの公開鍵レコードとともに X バックエンドから届きます。パスコードの保存とアンロックは Chat XDK の呼び出しです。initialize with existing keys および create and register keys を参照してください。サーバやボットではバックアップをスキップして、エクスポートされた鍵 blob を使うことがよくあります。それはパスワードと同じように保護してください。
署名の詳細
すべてのメッセージの署名は、受信者に次の 2 つの保証を与えます。- 真正性: 送信者の signing 秘密鍵の保持者によって生成されたものである
- 完全性: 暗号化されたコンテンツは署名後に改ざんされていない
reply_preview_validation(Valid / Invalid)として報告します。Invalid という結果は、引用が署名済みの元メッセージと一致していないことを意味します。返信自体は別途検証されているとはいえ、引用された内容は信頼できないものとして扱ってください。これにより、どの参加者も他者に偽の言葉を帰属させることはできなくなります。
署名付き状態変更(action signatures)
署名されるのはメッセージだけではありません。会話に対するすべての変更(グループ作成、メンバー追加、鍵のローテーション)にも action signature を伴わせる必要があります。送信者は、その変更が何を行うのかを正確に記述したペイロードに署名し、API はこれが欠落していたり不正な形式である場合、リクエストを拒否します。XDK があなたの代わりにこれを生成します。 サーバが鍵の変更を完全には検証できない理由。 サーバは生の会話鍵を保持しません(それがポイントです)。そのため、サーバは自身に見えない素材に対する署名を検証することはできません。サーバは可能な範囲、つまり署名された記述がリクエストと一致するかどうかを確認し、本当の意味での暗号的な確認は、受信者が鍵の変更をアンラップする際に行います。 イベントは不変です。検証に失敗したイベントは永続的に無効です。Troubleshooting を参照してください。セキュリティ特性
以下は X Chat が守るもの、そして同じくらい重要な、守らないものです。X Chat が守るもの
X Chat が守らないもの、およびその理由
Glossary
次のステップ
Getting Started
鍵、送信、受信を段階的に実装する
Chat XDK Reference
暗号化 SDK のメソッドと型
Introduction
製品概要とアーキテクチャ
Real-time events
暗号化されたイベントがどのように配信されるか