グループが 1:1 と異なる点
暗号処理は変わりません:鍵とペイロードには Chat XDK、グループの作成、参加者向け鍵ラップの公開、メッセージの送信、イベントのロードには X API。
グループを作成して鍵を確立する
POST /2/chat/conversations/group/initializeでグループ ID を発行します——レスポンスのdata.conversation_idが、以降どこでも使う g プレフィックス付きの ID です。- 各メンバーのアイデンティティ公開鍵と
public_key_versionをロードします(Encryption keys の下の公開鍵GETルート。GET /2/users/public_keysは複数のユーザーを 1 回のリクエストで取得します)。使用前に各レコードをverify_key_bindingで検証してください(はじめに の警告を参照)。 prepare_group_createを、すべてのメンバー(自分自身を含む)、g プレフィックス付きの ID、メンバー/管理者の ID リストとともに一度実行します。この 1 回の呼び出しで会話鍵を生成し、すべてのメンバー向けにラップし、set_identityからのセッションアイデンティティで作成に署名します——2 つのアクション署名を返します(会話鍵の変更とグループ作成)。POST /2/chat/conversations/groupに、グループメンバー/管理者、conversation_key_version、conversation_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."など。- 暗号化/復号のために生の会話鍵とバージョンを保持します。
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)のボディマッピングは、はじめに — 会話鍵 の keys POST と同じです。
メンバーシップが変わるときは、新しいメンバー ID と現在の名簿(メンバー、管理者、保留中のメンバー、および現在のタイトル/アバター/TTL が設定されていればそれら)とともに prepare_group_members_change を呼び出します。会話鍵をローテーションし、グループ作成と同様に2 つのアクション署名を返します——すべてを add members(POST /2/chat/conversations/{id}/members)に POST してください。その後、鍵変更トラフィックが来ることを想定してください:はじめにの鍵ローテーションと同じように扱ってください(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→ send-message API(はじめに) - 受信: events API またはリアルタイム配信 →
decrypt_event/decrypt_events - メディア: グループの会話 ID を使ったメディア
チェックリスト
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 と同じパターンで行う