Skip to main content
グループチャットは、1:1 の X Chat と同じ暗号化モデルを使用します: メンバーで共有する 1 つの会話鍵を、各メンバーの identity 公開鍵にラップし、メッセージは Chat XDK によって暗号化・署名されます。変わるのは、メンバーシップ会話の作成方法、そしてしばしば会話上の暗号化されたタイトル/アバターフィールドです。 1:1 のフローは Getting Started にあります。エンドポイントの詳細は API リファレンス → Conversations and messages の下にあります。

グループと 1:1 の違い

暗号処理は依然として: 鍵とペイロードには Chat XDK、グループの作成、参加者鍵ラップの公開、メッセージの送信、イベントのロードには X API です。

グループの作成と鍵の確立

  1. POST /2/chat/conversations/group/initialize でグループ ID を発行します — レスポンスの data.conversation_id は、以下のすべての箇所で使用する g プレフィックス付きの ID です。
  2. 各メンバーの identity 公開鍵と public_key_version をロードします(Encryption keys の下にある GET 公開鍵ルート;GET /2/users/public_keys は複数のユーザーを 1 回のリクエストで取得します)。使用前に各レコードを verify_key_binding で検証してください(Getting Started の警告を参照)。
  3. prepare_group_create を、すべてのメンバー(自分自身を含む)、g プレフィックス付き ID、メンバー/管理者 ID リストとともに一度実行します。1 回の呼び出しで会話鍵を生成し、すべてのメンバー用にラップし、作成に署名します — 2 つのアクション署名(会話鍵の変更とグループ作成)を返します。
  4. POST /2/chat/conversations/group に、グループのメンバー/管理者、conversation_key_versionconversation_participant_keys(SDK encrypted_key → API encrypted_conversation_key)、および両方action_signatures を送信します。検証失敗は、安定した人間が読めるメッセージとして返されます。たとえば "Too many members: adding these members would exceed the allowed group size.""Cannot add all members: one or more of the requested members cannot be added to this conversation." です。
  5. 暗号化/復号のために、未加工の会話鍵とバージョンを保持します。
prepare_group_create に渡す titleavatar_url は署名され、グループ作成イベントにそのまま埋め込まれます。サーバーはリクエストに対してそれらを照合します — したがって、POST ボディの group_name / group_avatar_url の値は SDK に渡したものとバイト単位で同一でなければなりません。そうでなければ、呼び出しは署名検証に失敗します。
参加者鍵とアクション署名のボディマッピング(message_idencoded_message_event_detail、ネストされた message_event_signature)は、Getting Started — conversation keys の鍵 POST と同じです。 メンバーシップが変更されたときは、prepare_group_members_change を新しいメンバー ID と現在のロスター(メンバー、管理者、保留中のメンバー、および設定されている場合は現在のタイトル/アバター/TTL)とともに呼び出します。会話鍵をローテーションし、グループ作成と同様に2 つのアクション署名を返します — すべてを add membersPOST /2/chat/conversations/{id}/members)に POST します。その後、鍵変更トラフィックが期待されます: Getting Started の鍵ローテーション のように扱います(extract_conversation_keys / decrypt_events、その後最新バージョンで暗号化)。 prepare_group_members_change は、渡したロスターにのみラップされた新しい会話鍵を生成するため、新しいメンバーは新しい鍵バージョンを受け取り、以前のバージョンで送信されたメッセージを復号できません。その逆は真ではありません: ローテーションは以前のバージョンへのアクセスを取り消しません — 古い鍵をすでに持っている人は、その下で暗号化されたメッセージを読み続けることができます。会話鍵が漏洩したと疑われる場合は、prepare_conversation_key_change でローテーションしてください;これは将来のメッセージのみを保護します。

暗号化されたグループメタデータ

一部の会話フィールド(たとえば表示アバター URL)は、会話鍵で暗号化された状態で到着することがあります。これは encrypt_message ではありません。汎用の Chat XDK encrypt / decrypt のペア(UTF-8 文字列入力、base64 暗号文出力、未加工の会話鍵を使用)です。 特定のフィールドが暗号化されて保存されるかどうかは、それを書き込むクライアントによって決定されます: prepare_group_create は、提供されたとおりにタイトルに署名して送信します(会話鍵はその呼び出しが生成するまで存在しないため、作成時のタイトルはその下で暗号化できません)。フィールドが暗号文である会話を読むときは、フィールドが書き込まれたときにアクティブだった鍵バージョンで decrypt して復号します。
そのメタデータに適用される現在の会話鍵バージョンを使用してください。鍵がローテーションされている場合は、フィールドが書き込まれたときにアクティブだったバージョンで復号してください(または、メタデータがローテーション時に常に書き換えられる場合は製品のルールに従ってください)。

メッセージとイベント

グループでの送受信は、未加工の会話鍵を持てば 1:1 と同じです:
  • 送信: encrypt_message → メッセージ送信 API(Getting Started
  • 受信: イベント API またはリアルタイム配信decrypt_event / decrypt_events
  • メディア: グループの会話 ID を使った Media
メンバーシップに起因するローテーション後は、常に最新の鍵バージョンで暗号化してください。

チェックリスト

  1. POST /2/chat/conversations/group/initialize で g プレフィックス付き ID を発行する
  2. すべてのメンバーで prepare_group_create;参加者鍵ラップと両方のアクション署名を POST /2/chat/conversations/group に POST する
  3. 未加工の鍵 + バージョンをキャッシュ;鍵変更イベントで更新する
  4. メンバーシップ変更時は prepare_group_members_change(2 つの署名)→ POST /2/chat/conversations/{id}/members
  5. フィールドが暗号文の場合は decrypt でグループメタデータを復号する
  6. 1:1 と同じパターンで送受信する