Skip to main content
X 上でエンドツーエンド暗号化されたダイレクトメッセージを送受信します: 鍵をセットアップし、会話を初期化し、メッセージを送信し、受信トラフィックを復号します。 X Chat アプリは、2 つの要素を組み合わせて使用します:
前提条件
  • 開発者アカウント と OAuth 2.0 用に構成されたアプリ
  • dm.readdm.writetweet.readusers.read を持つユーザーアクセストークン

1. 依存関係をインストールする

PyPI パッケージは chatxdk です。chat_xdk としてインポートします。Python 3.10+ が必要です。
ユーザー OAuth 2.0 アクセストークンで API クライアントを作成します:

2. 既存の鍵で Chat XDK を初期化する

このステップでは、すでに持っている鍵をロードします — この identity が過去に初回セットアップを完了している場合に使用してください:
  • 安全な鍵バックアップ: 公開鍵レコードの juicebox_config で SDK を構築し、パスコードで unlock して秘密鍵を復元します(たとえば新しいデバイスで)。
  • 鍵 blob: 以前に export_keys でエクスポートした blob を import_keys に渡します。
次に、登録済みの公開鍵バージョン(レコード上の public_key_version)を設定します。 初めてセットアップする場合は? 同じ方法で SDK を構築しますが、unlock / import_keys はスキップし、ステップ 3 に進んで鍵の作成、バックアップ、登録を行ってください。
サーバーおよびボットのサンプルでは、通常鍵 blobexport_keys / import_keys)を使用します。クライアントアプリでは通常安全な鍵バックアップ(パスコードを使った setup / unlock)を使用します。両方のパスについては Chat XDK リファレンスを参照してください。
独自の鍵を持ち込みますか? import_keys は、Chat XDK の export_keys が生成する不透明な blob のみを受け付けます — これは鍵の完全な状態をバージョン付きで非公開にシリアライズしたものであり、未加工または PEM エンコードされた P-256 鍵ではありません。この blob を自分で構築することはできません: generate_keypairsステップ 3)で鍵を生成し、blob を一度エクスポートして、base64 エンコードで保存してください。手作りまたは改変された blob はインポートに失敗します。

3. 鍵を作成して登録する(初回セットアップ)

ステップ 2 で既存の鍵をロードした場合は、このステップをスキップしてください。それ以外の場合、新しい identity の 1 回限りのセットアップでは 3 つのことを行います:
  1. キーペアを作成するgenerate_keypairs が identity と署名のキーペアを生成します。
  2. 公開鍵を登録する — 他のユーザーがあなた宛てに暗号化し、あなたの署名を検証できるよう、登録ペイロードを add-public-key エンドポイントに POST します。
  3. 秘密鍵を保存する — パスコードで setup すると安全な鍵バックアップに書き込まれます(クライアント)。または export_keys が返す鍵 blob を安全に保存します(サーバーとボット)。
安全な鍵バックアップには強力なパスコードを使用してください。パスコードを紛失したり、保護されていない鍵 blob を失うと、過去のメッセージの復号ができなくなる可能性があります。

4. 会話鍵をセットアップする

prepare_conversation_key_change を、あなたのユーザー ID、署名鍵のバージョン、およびすべての参加者の identity 公開鍵とともに呼び出します。1 回の呼び出しで新しい会話鍵を生成し、各参加者向けに暗号化し、変更に署名します。結果を add conversation keys エンドポイント(POST /2/chat/conversations/{id}/keys)に POST します — ボディには conversation_key_versionconversation_participant_keys(SDK の encrypted_key → API の encrypted_conversation_key)、および action_signatures が必要です(必須;API は署名がないと呼び出しを拒否します)。送信用に未加工の会話鍵を保持します。 レスポンスは、正規の会話 ID(data.conversation_id — 1:1 の場合はハイフンで結合されたペア、グループの場合は g プレフィックス付き ID)と、鍵変更の data.sequence_id を返します。以降のリクエストでは、クライアント側で再構築するのではなく、返された ID を使用してください。同じ呼び出しは後で鍵をローテーションするためにも使えます: 既存の会話 ID を prepare_conversation_key_change に渡し、新しい鍵バージョンで POST します。会話鍵が漏洩したと疑われる場合はローテーションしてください — ローテーションは将来のメッセージのみを保護します;以前の鍵バージョンで暗号化されたメッセージは、そのバージョンを保持している人にとっては引き続き読み取り可能です。
ラップする前に取得した鍵を検証してください。 prepare_conversation_key_change は、渡された任意の公開鍵に対して新しい会話鍵を暗号化します。各取得済みレコードに対してまず verify_key_binding(identity, signing, signature) でチェックし(public-keys API のレコードの public_keysigning_public_keyidentity_public_key_signature フィールドを渡します)、置き換えられた identity 鍵が会話鍵を受け取れないようにしてください。

5. メッセージを送信する

未加工の会話鍵バイトで暗号化します。送信リクエストでは、次のようにマップします: API で要求される場合、URL パスではハイフン付きの会話 ID を使用します(:-)。SDK 自体は柔軟です: encrypt_messageencrypt_reply は、保持している任意の形式で ID を受け付けます — イベントからの A:B、リストや URL パスからの A-B(どちらの順序でも可)、あるいは受信者のユーザー ID だけでも構いません — そして署名する前に正規化します。グループ ID(g プレフィックス付き)はそのまま渡されます。

6. 受信して復号する

ライブトラフィックには Webhook またはアクティビティストリーム を使用します。履歴には会話イベントをページングします。
  • ライブペイロードのフィールド: encoded_event、オプションの conversation_key_change_event
  • 履歴: GET /2/chat/conversations/{id}/events — 全イベントに対する decrypt_events に加えて meta.conversation_key_events を優先
  • 署名検証のために送信者の公開鍵を decrypt に渡します(API フィールドを SigningKeyEntry にマップします;Chat XDK を参照)
  • JavaScript は camelCase のイベントタイプ(message)を使用します;他の言語は JSON で "Message" と snake_case フィールドを使用します
全言語向けの完全なポール&リプライボット: chat-xdk/examples

ベストプラクティス

  • 未加工の会話鍵と送信者の公開鍵をキャッシュし、署名検証が失敗した場合は更新する
  • event_uuid でライブ配信の重複を排除する
  • ページネーションが完了するまでイベント履歴をページングし、鍵変更のメタデータを見逃さないようにする
  • 本番環境でパスコード、秘密鍵、メッセージ平文をログに残さない
  • Web アプリでは、OAuth トークン(および鍵バックアップ realm トークン発行)をサーバー側で保持し、秘密鍵はクライアントの Chat XDK 内でのみ保持することが望ましい

次のステップ

Chat XDK

すべての言語バインディングのメソッドと型

Media

暗号化された画像とファイル添付

Groups

複数参加者の会話とメタデータ

Real-time events

Webhook とアクティビティ配信