グループと 1:1 の違い
暗号処理は依然として: 鍵とペイロードには Chat XDK、グループの作成、参加者鍵ラップの公開、メッセージの送信、イベントのロードには X API です。
グループの作成と鍵の確立
POST /2/chat/conversations/group/initializeでグループ ID を発行します — レスポンスのdata.conversation_idは、以下のすべての箇所で使用する g プレフィックス付きの ID です。- 各メンバーの identity 公開鍵と
public_key_versionをロードします(Encryption keys の下にあるGET公開鍵ルート;GET /2/users/public_keysは複数のユーザーを 1 回のリクエストで取得します)。使用前に各レコードをverify_key_bindingで検証してください(Getting Started の警告を参照)。 prepare_group_createを、すべてのメンバー(自分自身を含む)、g プレフィックス付き ID、メンバー/管理者 ID リストとともに一度実行します。1 回の呼び出しで会話鍵を生成し、すべてのメンバー用にラップし、作成に署名します — 2 つのアクション署名(会話鍵の変更とグループ作成)を返します。POST /2/chat/conversations/groupに、グループのメンバー/管理者、conversation_key_version、conversation_participant_keys(SDKencrypted_key→ APIencrypted_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."です。- 暗号化/復号のために、未加工の会話鍵とバージョンを保持します。
prepare_group_create に渡す title と avatar_url は署名され、グループ作成イベントにそのまま埋め込まれます。サーバーはリクエストに対してそれらを照合します — したがって、POST ボディの group_name / group_avatar_url の値は SDK に渡したものとバイト単位で同一でなければなりません。そうでなければ、呼び出しは署名検証に失敗します。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
message_id、encoded_message_event_detail、ネストされた message_event_signature)は、Getting Started — conversation keys の鍵 POST と同じです。
メンバーシップが変更されたときは、prepare_group_members_change を新しいメンバー ID と現在のロスター(メンバー、管理者、保留中のメンバー、および設定されている場合は現在のタイトル/アバター/TTL)とともに呼び出します。会話鍵をローテーションし、グループ作成と同様に2 つのアクション署名を返します — すべてを add members(POST /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 して復号します。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
メッセージとイベント
グループでの送受信は、未加工の会話鍵を持てば 1:1 と同じです:- 送信:
encrypt_message→ メッセージ送信 API(Getting Started) - 受信: イベント API またはリアルタイム配信 →
decrypt_event/decrypt_events - メディア: グループの会話 ID を使った Media
チェックリスト
POST /2/chat/conversations/group/initializeで g プレフィックス付き ID を発行する- すべてのメンバーで
prepare_group_create;参加者鍵ラップと両方のアクション署名をPOST /2/chat/conversations/groupに POST する - 未加工の鍵 + バージョンをキャッシュ;鍵変更イベントで更新する
- メンバーシップ変更時は
prepare_group_members_change(2 つの署名)→POST /2/chat/conversations/{id}/members - フィールドが暗号文の場合は
decryptでグループメタデータを復号する - 1:1 と同じパターンで送受信する