プライバシー保護に関するセキュリティホワイトペーパー

1 はじめに

Wireは、Android、iOSデバイス、Windows、macOS、Linux、およびブラウザのWeb上で動作します。登録されたユーザーは、ユーザーのすべてのデバイス間で内容が同期された会話に参加します。
このドキュメントでは、ユーザーのプライバシーを保護するために実装されている暗号プロトコルとセキュリティの概要を説明します。

2 登録

Wireでの登録には最大3段階のステップが必要で、サービスの利用を開始するには最初のステップのみが厳密に必要となります。

  1. ユーザー登録。
  2. クライアント登録。
  3. プッシュトークンの登録。

2.1 ユーザー登録

Wireは2つの基本的な登録フローをサポートしており、オプションで構成することができます。すべてのフローに共通しているのは、プロファイル名を提供する必要があるということですが、これは一意である必要はありません。収集されるデータの詳細については、Wire プライバシーホワイトペーパーを参照してください。

2.1.1 電子メールでの登録

電子メールによる登録(図2.1)には、プロファイル名と有効な電子メールアドレスが必要です。メールアドレスを確認するために、サーバはランダムな検証コードc∈R [0, 2 192 – 1]を生成し、それを指定されたメールアドレスに送信して登録を完了させます。サーバは、正しい検証コードを送信するために3回しか試行できませんが、その間に自動的に無効化され、新しい検証コードを要求する必要があります。検証コードの有効期限は2週間です。

 

図 2.1: ユーザー登録(電子メール)

登録が成功すると、クライアントはWire内部ID(UUID v4)と認証クッキーを受け取ります。

2.1.2 電話での登録

電話番号による登録(図2.2)では、プロファイル名と有効な電話番号が必要です。クライアントアプリケーションは、実際の登録要求を送信する前に、サーバに検証コードc∈R [0, 106 – 1]をSMSでユーザが提供した電話番号に送信するように要求します。実際の登録要求には、cが含まれています。クライアントは、正しい検証コードが無効になる前に、正しい検証コードを送信するために3回しか試行できません。検証コードは2週間後に有効期限が切れます。

登録が成功すると、クライアントはWire内部ID(UUID v4)と認証クッキーを受け取ります。

2.1.3 パスワード

パスワードはサーバ上にプレーンテキストとして保存されるのではなく、代わりに、パラメータN = 214、r = 8、p = 1、ランダムなソルトs∈R [0, 2256 −1]を指定して、scryptキー導出関数に渡されます。結果として得られたハッシュは、ソルトとパラメータと共にlog2 N||r||p||base64(s)||base64(hash)の形式で保存されます。クライアントはパスワードを揮発性メモリに保存します。

 

図 2.2:ユーザー登録(電話)

2.1.4 その他のデータ

以下の追加データがサーバーに保存されています。

  • Locale:ユーザーの希望する言語を表すIETF言語タグ。
  • アクセントカラー:数値定数。
  • Picture(画像):以前にアップロードされた公開プロフィール画像に関するメタデータで、固有のID、寸法、タグが含まれます。
  • Cookie Label(クッキー ラベル):登録に成功した際に HTTP クッキーとして返されるユーザー トークンに関連付けるラベル。
  • Webアプリの設定:絵文字設定、リンクプレビュー設定、サウンドアラート設定などの設定が保存されます。

2.2 クライアント登録

エンドツーエンドの暗号化コンテンツの交換に参加するためには、クライアント登録(図2.3)が必要です。暗号化されたコンテンツは2つのクライアント間で交換されるため、ユーザアカウントの概念はあまり関係ありません。

ユーザーは合計で最大8つのクライアントアプリケーション(通常は異なるデバイス)を登録することができます: 7つの恒久的なクライアントは1つの一時的なものです。7つ以上の恒久的なクライアントを登録しようとすると、エラーが発生し、恒久的なクライアントを削除する必要があります。新しい一時的なクライアントを登録すると、古いクライアントが置き換えられます。

メッセージはクライアント間で個別に暗号化されるため、これらの制限は、暗号化されたメッセージを送信する際にクライアントが実行する必要のある計算量を制限します。

プレキーは、新しく登録されたクライアントとの暗号化セッションを開始するために他のクライアントによって使用され、8ページの4.1.1項で定義されています。

 

図 2.3: クライアント登録

クライアント登録が成功すると、サーバーはユーザーIDごとに一意なクライアントID(Cid)を返します。

2.2.1 その他のデータ

また、クライアント登録時には以下のデータを収集します。

  • クラス:デバイスのクラス:モバイル、タブレット、またはデスクトップ。
  • モデル:デバイスのモデル、例:iPhone 7。
  • Label (ラベル) :同じクラスやモデルのデバイスを区別するための人間が読めるラベル。
  • Cookie ラベル:クッキーラベルは、クライアントを認証クッキーにリンクします(次ページの第3節を参照)。そのようなクライアントが後でアカウントから削除された場合、つまりデバイスが紛失した場合、サーバは一致するクッキーラベルを持つ認証クッキーを取り消すでしょう。一度設定したクッキーラベルは決して変更できません。
  • パスワード: ユーザがパスワードを持っている場合、クライアントの登録には、アカウントの最初の登録クライアントを除いて、このパスワードでの再認証が必要です。同様に、登録されたクライアントを削除するには、パスワードの入力も必要です。

2.2.2 メタデータ

サーバは、新規登録されたクライアントごとに以下のメタデータを収集し、ユーザに公開します。

  • タイムスタンプ:クライアントが登録された UTC タイムスタンプ。
  • ロケーション:クライアントの登録に使用されるIPアドレスの地理的座標。

この情報は、新規登録に関する通知をより意味のあるものにするためにのみ収集されます。

 

図2.4: プッシュトークンの登録

2.2.3 通知

新規顧客がアカウントに登録されると、同じアカウントの既存顧客全員にその旨が通知されます。さらに、ユーザーには電子メールで通知されます。これらの通知は、ログイン認証情報が盗まれた場合など、アカウントに登録されている不審なクライアントを特定するのに役立ちます。

2.3 プッシュトークンの登録

最終的な登録ステップとして、クライアントは、デバイスがオフラインのとき(開いている Websocket 接続がないとき)に FCM または APN を介してプッシュ通知を受信するためにプッシュトークンを登録することができます。プッシュ通知の詳細については、10ページの4.5項を参照してください。

3 認証

3.1 トークン

API 認証は、アクセストークンと呼ばれる短命のベアラートークンと、長寿命のユーザートークンの組み合わせに基づいています。アクセストークンは保護された API リソースへのリクエストを認証するために使用され、ユーザートークンは新しいアクセストークンを継続的に取得するために使用されます。

ユーザートークンは HTTP クッキーとして送信されます。すべてのトークンはサーバによって署名された文字列で、ユーザーID(UUID v4)と有効期限をUnixタイムスタンプとして含みます。ユーザートークンとアクセストークンの完全な形式は、14 ページの付録 A で指定されています。

ユーザー・トークン、ひいてはクッキーのスコープは、HTTP プロトコルで指定されたものと同じセマンティクスで、永続的またはセッション・ベースにすることができます。クライアントはログイン中にクッキーのスコープを選択します。HTTP クッキーの属性は、その使用をバックエンド・サーバのドメイン、トークンの更新エンドポイントのパス、および HTTPS プロトコルに制限します。永続的なクッキーはクライアント上の永久的で安全なストレージに保存されますが、セッション・クッキーは一時的なストレージ(ブラウザ・セッションなど)にのみ保存されます。永続的クッキーの有効期限は 1 年、セッションクッキーの有効期限は 1 週間です。

 

図 3.1: トークンの更新

 

図 3.2: パスワードによるログイン

アクセストークンは比較的短命(15分)です。期限切れのアクセストークンを更新するために、クライアントはクッキーを使用してアクセストークンを更新します。クッキーが有効な場合は、新しいアクセストークンが生成されて返されます。アクセストークンが更新されると、サーバはさらに新しいクッキーを発行して、有効期限を継続的に延長することができます(図3.1)。このようなクッキーの更新は通常約3ヶ月ごとに行われます。

ユーザーは最大32個の永続的クッキーと32個のセッションクッキーを持つことができますが、これらはいずれも透過的に最新のものから最新のものに置き換えられます。

初期登録後、ユーザーログインのみが、新しい長寿命のユーザートークンとアクセストークンを生成することができます。

Wireは、以下の2種類のログインをサポートしています。

3.2 ログイン

アカウントにパスワードを追加したユーザー、または電話番号を確認したユーザーはログインすることができます。ログインはセッションまたは永続的なログインとして分類され、結果として得られるクッキーの希望する範囲に対応します。クライアントはログインのタイプを選択できます。

3.2.1 パスワードログイン

パスワードを使ってログインするには、クライアントはユーザー ID、電子メール アドレス、または電話番号とパスワードを提供し、これらは TLS を介して送信されます。サーバは scrypt を使用してパスワードを検証し、図 3.2 に示すように、HTTP クッキーと新しいアクセストークンとして新しいユーザートークンを発行します。

3.2.2 SMSログイン

認証された電話番号で登録したユーザーは、SMSでログインすることができます。手続きは登録時と同じで、同じ制限がありますが、SMSのログインコードは10分後に有効期限が切れてしまいます。

3.3 パスワードのリセット

Wireは、パスワードと検証済みの電子メールアドレスまたは電話番号を持つ登録ユーザに対して、セルフサービスによるパスワードリセットを提供します。

検証済みの電話番号または電子メールアドレスを介したパスワードリセットの手順は、最初の検証(図2.1および2.2参照)と似ていますが、以下の違いがあります。

  • 1 つのアカウントに対して保留中のパスワードリセットは、常に 1 回のみ可能です。タイムアウトウィンドウの期限が切れる前に新しいパスワードリセットを開始することはできません。
  • パスワードリセットコードの有効期限は1時間です。

4 メッセージング

メッセージングとは、テキストメッセージとアセットの交換を指します(4.3項)。Wireのすべてのメッセージングは、エンドツーエンドの暗号化の対象となり、ユーザーに強力なプライバシーとセキュリティを提供します。

4.1 エンドツーエンドの暗号化

エンドツーエンド暗号化(E2EE)は2つのクライアント間で行われる(2.2参照)。Proteus は主要な暗号化プロトコルです。これはAxolotl/Double Ratchetプロトコルの独立した実装であり、異なるラチェットを使用して Offthe-Recordプロトコルから派生したものです。

さらに、Wireでは、非同期環境でプロトコルを使用するためにプレキーの概念を使用しています。暗号化された会話を開始するために、2つの当事者が同時にオンラインである必要はありません。

Proteusは以下の暗号化プリミティブを使用しています(libsodiumによって提供されています)。

  • ChaCha20 ストリーム暗号
  • MACとしてのHMAC-SHA256
  • 楕円曲線Diffie-Hellmanキー交換 (Curve25519)

キーの導出にはHKDFを使用しています。

4.1.1 プレキーズ

各クライアントは最初に、ローカルに保存されているいくつかのキー材料を生成します。

  • アイデンティティのキーペア:(a, ga)∈R Zp × Curve25519 ここで、g∈Curve25519
  • プレキーの集合:(k(a,i), gk(a,i) ) ∈R Zp × Curve25519 ここで、0 ≤ i ≤ 65535

クライアント登録(2.2 節)の間に、クライアントは公開 ID キー ga をバンドルしたプレキー (gk(a,0) , …, gk(a,j) ) をアップロードします。すなわち、受信者のプレキー gk(a,i) と ID キー ga が与えられると、送信者は受信者がオフラインであっても n 個の初期暗号化キーを導出することができます。

ID 65535 のプレキーは、いわゆる「最後の手段」のプレキーです。すべてのプレキーは一度だけ使用されることを意図しており、サーバは要求されたすべてのプレキーを直ちに削除します。プレキーを使い切らないようにするために、最後の手段のプレキーは決して削除されず、クライアントは定期的に新しいプレキーをアップロードする必要があります。

残りのプロトコルフローとそのセキュリティ特性の詳細については、参考文献[8]、[9]、[10]、[13]を参照してください。

4.2 メッセージ交換とクライアント発見

暗号化されたメッセージを送信するには、送信側のクライアントはメッセージを送信したいすべてのクライアント(通常は特定の会話に参加しているすべてのクライアント)と暗号化セッションを持つ必要があります。すべての受信者に対してプレーンテキストメッセージを暗号化し、バッチをサーバに送信します。サーバは、会話の参加者であるすべてのユーザのすべてのクライアントがバッチに含まれているかどうかをチェックします。クライアントが見つからない場合、サーバはリクエストを拒否して、見つからないクライアントを送信者に通知します。送信者は、欠落しているクライアントのプレキーを取得し、残りのメッセージを準備してからバッチ全体を再送することができます。

同じメカニズムにより、クライアントは、冗長なクライアント、すなわち、暗号化メッセージを準備したが、もはや会話の一部ではないクライアントについても通知されます。これには、削除されたクライアント、すなわち、冗長で削除されたことが知られているクライアントも含まれます。送信者はこの情報を使用して、会話に参加しているクライアントのリストと対応する暗号化セッションを更新することができます。

メッセージの送信者に対するクライアント発見を図4.1に示します。

逆に、クライアントが以前の暗号化セッションが存在しない別のクライアントから暗号化されたメッ セージを受信した場合、クライアントは暗号化されたメッセージから新しい暗号化セッションを初期化します。

中間者攻撃を排除するために、ユーザは帯域外の ID キーの指紋を比較する必要があります。

 

図4.1. クライアントの発見(送信者)

4.3 アセット

アセットとは、画像などのユーザー間で送信されるより大きなバイナリエンティティのことです。

プロフィール写真は、技術的なメタデータ(幅、高さ、ファイルタイプなど)を持つ平文のアセットとしてアップロードされ、ユーザーのプロフィールを通じて共有されます。

会話で共有されるその他のアセットは、エンドツーエンドで暗号化されます。通常のテキストメッセージと比較して、アセットの暗号化は、送信者に必要な計算オーバーヘッドとネットワーク帯域幅を削減するために提案された最適化を適用します。Wireでは、送信クライアントは次のように行います。

  1. AES-256 で使用するためのランダムな対称キー k を生成します。
  2. CBC モードで PKCS#5/7 パディングを用いてアセットデータを k で暗号化し、その結果得られる暗号文の SHA-256 ハッシュを計算します。
  3. Proteus プロトコルを介して、各受信者のキー k とハッシュ、その他のアセットメタデータを暗号化します。
  4. 暗号化されたアセットデータと、各受信者のための暗号化されたメタデータのペイロードをサーバに送信します。

その後、アセット・メタデータ・メッセージを受信したクライアントは、以下の処理を行います。

  1. アセットメタデータを Proteus プロトコルを用いて復号化し、対称キー k とアセット暗号文の SHA-256 ハッシュを取得します。
  2. アセット暗号文をダウンロードし、SHA-256 ハッシュを計算し、受信したハッシュと比較してアセットデータの完全性を検証します。
  3. キー k を用いてアセットデータを復号化します。

通常のテキストメッセージと同様に、同じ会話に参加しているクライアントのみが、互いにアセット・メタデータ・メッセージを受信することができ、対応するアセット暗号文のダウンロードを許可されます。

アセットは、事前に定義されたタイムアウトなしにサーバに永続的に保存されます。これは、クライアントが復号化された対称キー k を SHA-256 ハッシュとともに永続的に保存するため、クライアントは同じアセットを繰り返しダウンロードして復号化し、デバイス上のディスク容量を節約することができることを意味します。これらの認証情報は、平文アセット自体の機密性と同じです。復号キー k は Proteus プロトコルを使用して送信されるため、前方秘匿性は影響を受けません。

4.4 リンクプレビュー

ユーザーがリンクを共有すると、アプリはリンクプレビューを生成することができます。この機能はオプションで、オフにすることができます。リンクプレビューは、リンク先のウェブサイトからオープングラフデータ(画像と一部のテキスト)を取得することで、送信者側のみで生成されます。データは受信者に送信され、そこに表示されますが、受信者はリンクがクリックされたりタップされたりしない限り、ウェブサイトへのネットワークリクエストは行いません。

4.5 通知

メッセージは、サーバーから通知を介して受信者に配信されます。通知は、3つの異なるチャネルを介してWireによって配信されます。

Websocket 接続:すべての認証済みクライアントは、HTTPS を介して Websocket 接続を確立することができます。確立された Websocket 接続を持つクライアントはオンラインと見なされます。

外部プッシュプロバイダ:Wireは現在、外部プッシュプロバイダとしてFCMとAPNをサポートしています。このチャネルは、クライアントがオフラインであるにもかかわらず、有効なFCMまたはAPNのプッシュトークンをサーバーに登録している場合に使用されます。コンテンツは暗号化され、外部プッシュプロバイダからは見えません。

通知キュー:ユーザによって送信されたすべてのメッセージと、ほとんどのメタデータメッセージは、ユーザの登録された、認証されたすべてのクライアントによって照会(およびフィルタリング)されることができる、クライアントごとの通知キューに格納されています。この通知キューは、ユーザの登録された認証済みクライアントごとにクエ リすることができます (そしてフィルタリングすることができます)。通知の保持期間は4週間です。

5 呼び出し

Wireユーザーは、1:1またはグループ会話でお互いに通話することができます。通話は会話のすべての参加者に対して開始され、その会話の参加者ではないユーザーは通話にアクセスできません。すべての通話は、エンドツーエンドで暗号化されています。

通話の設定には、シグナリング、メディアトランスポート、および暗号化の3つの側面が含まれます。これらについては、次に詳しく説明します。

5.1 コールシグナリング

コールシグナリングは、クライアント間の接続を確立し、SDPメッセージを交換することで共通の機能をネゴシエートします。これらのメッセージは、テキストメッセージと同じ暗号化を使用して、Proteusメッセージとしてクライアント間で送信されます。

5.2 メディアトランスポート

接続されると、エンドポイントはそれらの間のメディアのトランスポート・パスを決定します。可能な限り、エンドポイントはそれらの間で直接メディアの流れを許可しますが、ネットワークによってはファイアウォールやNATが直接ストリーミングを妨げ、代わりにTURNサーバを介してメディアを中継する必要がある場合があります。ICE は、最適なトランスポート・パスを識別します。

TURNサーバは、Wireインフラストラクチャの一部ですが、それを使用するユーザのユーザIDを知りません。クライアントは一般的な資格情報を使用してTURNサーバに対して認証を行うため、TURNサーバでは通話が区別できません。そのため、TURNサーバは、識別可能なコールレコードをログに記録することができません。

5.3 暗号化

通話メディアは、SRTP 暗号化されたメディアセッションでエンドポイント間で交換されます。セッションを開始するには、SRTP 暗号化アルゴリズム、キー、パラメータが DTLS ハンドシェイクによってネゴシエートされます。クライアントの真正性は、ハンドシェイク中にも検証されます。

通話のエンドポイントが 2 台の電話機である場合 (WebRTC との互換性が必要ない場合)、Wire は DTLS の代わりに KASE (Key Agreement Signaling Extension) を使用します。この利点は、キーネゴシエーションがシグナリングフェーズで事前に行われるため、通話をより迅速に接続できることです。DTLS と KASE の両方で、キーネゴシエーションは Proteus メッセージによって認証されます。

グループ通話では、各参加者は、1:1通話のように他の参加者に接続します。したがって、グループ通話のすべてのレッグは個別に暗号化され、暗号化キーは参加者間で共有されません。

5.4 エンコーディング

ストリーミングに使用するコーデックは、音声がOpus、動画がVP8です。Opusでは可変ビットレートエンコーディング(VBR)または一定ビットレートエンコーディング(CBR)を使用することができます。ユーザーは設定でCBRを有効にするかどうかを選択できます。CBRは、パケット長に関する潜在的に望ましくない情報を排除できるという利点がありますが、低速ネットワークでは通話品質に影響を与える可能性があります。コールの2つの当事者のうちの1つがCBRオプションを有効にしていれば十分であり、そのユーザーのコールには常にCBRが使用されます。CBRが使用されると、通話画面には「CONSTANT BIT RATE」が表示されます。グループ通話では、CBRオプションは、CBRオプションを有効にした参加者に接続された脚にのみ適用されます。すべてのレッグがCBRエンコーディングを使用するようにオプションを設定するのは参加者次第です。グループ通話の通話画面には、オプションが設定されていても「CONSTANT BIT RATE」は表示されません。ビデオ通話では、CBRオプションはオーディオ通話と同様にオーディオストリームに影響を与えますが、通話画面には「CONSTANT BIT RATE」は表示されません。

5.5 WebRTC

Wireは、WebRTCおよび既存のIETF標準に完全に準拠しています。その結果、Wireネイティブエンドポイントは、Google ChromeやMozilla FirefoxなどのWebRTC準拠のWebブラウザと安全にメディアを交換することができます。

これらは、Wireで使用されている主なIETF規格です。

• UDP (RFC 768[21])
• RTP (RFC 3550[22])
• ICE (RFC 5245[23])
• STUN (RFC 7350[24])
• TURN (RFC 5766[25])
• SDP (RFC 4566[26])
• SRTP (RFC 3711[27])
• DTLS (RFC 4347[28])
• DTLS-SRTP (RFC 5764[29])
• Opus (RFC 6716[30])

6 検証

4.1 で述べたように、各クライアントは独自の暗号 ID を持っています。中間者攻撃が行われないようにするために、暗号IDは帯域外で検証されるべきです。そのためには、会話中の各クライアントの指紋を見て比較することができます。比較した後、クライアントは検証済みとしてマークされます。会話中のすべてのクライアントが検証済みとしてマークされると、会話自体が検証済みの会話として扱われ、会話名の横に青いシールドが表示されます。

検証済みの会話に新しいクライアントが追加された場合、ユーザーはシステムメッセージで警告されます。新しいクライアントが検証されるまで、青いシールドは消えます。

7 更なる暗号化と保護

7.1 トランスポートの暗号化

Wireクライアントは、TLSv1.2 のみをサポートする HTTPS 接続を介してバックエンドサーバと対話します。前方秘匿(PFS)をサポートする暗号スイートのみが使用されます。サーバは、暗号スイートの優先順位を示し、すべてのクライアントに HTTP Strict Transport Security を通信します。不正な認証局や危殆化した認証局、またはクライアント側にインストールされたルート証明書によって引き起こされる中間者攻撃を緩和するために、Wireクライアントは、リーフ証明書の公開キーをハードコード化された値のセットに固定します。

クライアントは、HTTP リソースへのリクエストに加えて、Websocket 接続を維持してリアルタイムのプッシュ通知を受信したり、FCM や APN などの外部トランスポートを介してプッシュ通知に登録したりすることができます。プッシュ通知の詳細については、10 ページの 4.5 項を参照してください。

7.2 ローカルデータ保護

Wireアプリは、テキストメッセージ、画像、その他のアセットなどの会話の内容をデバイスのローカルに保存します。プラットフォームによって、異なる保護メカニズムが存在します。

  1. iOSでは、ローカルデータはコアデータを使用してファイルに保存されます。ローカルデータは、コアデータを使用してファイルに保存されます(どちらもNSFileProtectionCompleteUntilFirstUserAuthenticationで保護されています)。会話コンテンツ、暗号化キーの素材、その他の機密データは、iCloudまたはiTunesのバックアップと同期されません。ローカルデータはWireアプリからのみアクセス可能で、iOSのサンドボックス化により他のアプリからはアクセスできません。
  2. Android:ローカルデータはSQLiteを使用してファイルに保存されます。会話内容や暗号キー素材などの機密データは、Androidバックアップサービスでは同期されません。ローカルデータはWireアプリからのみアクセス可能で、Androidのパーミッションにより他のアプリからはアクセスできません。アプリは、外部ストレージ(SDカード)にキャッシュされたデータ(ダウンロードした画像など)を保持することがあります。これらのファイルはAES128を使用して暗号化されており、各ファイルはプライベートデータベースに保存されている異なるランダムキーを使用しています。
  3. デスクトップクライアント:ローカルデータはIndexedDBを使用して保存されます。データはユーザーのフォルダに保存されます。macOSではFileVault、WindowsではBitlockerのようなフルディスク暗号化を使用することを強くお勧めします。

7.3 アプリロック

iOSでは、アプリの設定(設定、オプション、パスコードでロック)に、アプリのロック機構を有効にするオプションがあります。デバイスのロックを解除するのと同じ方法で、TouchID/FaceIDまたはパスコードでアプリをロック解除することができます。

7.4 バックアップ

iOSでは、バックアップはXChaCha20Poly1305で暗号化され、キーの導出にはArgon2が使用されています。

コメント

タイトルとURLをコピーしました