鍵とセキュアキーバックアップ
アンロックに失敗する(無効なパスコード)
- パスコードが
setupで使用したものと一致していることを確認してください - 試行の間に待機してください。レルムは誤答をレート制限し、失敗が多すぎると復元をロックすることがあります
- Python
- TypeScript
- Rust
- Go
- C#
- Java
鍵やアイデンティティがセットされていないため暗号化/復号が失敗する
まず秘密鍵をロードし、次にセッションアイデンティティを設定してください——あなたのユーザー ID と、X 上のレコードのpublic_key_version です。encrypt_* および prepare_* メソッドはこれで署名します。セッションアイデンティティなし(かつ明示的な呼び出し単位のオーバーライドもなし)でこれらを呼び出すとエラーになります。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
ローカルの公開鍵がアカウントに登録されている鍵と一致しない
クライアントはしばしば 「このデバイス上の鍵は、このアカウントに登録されている鍵のいずれかに一致するか?」 に答える必要があります——復元やインポート後に、正しいpublic_key_version を採用するため、あるいはオンボーディングがすでに完了しているかを判定するためです。Chat XDK の get_public_keys の出力を API の public_key フィールドと文字列として比較すると、同じ鍵であっても常に失敗します。両者が異なるエンコーディングを使っているからです:
- API は登録時にアップロードされたそのままの形で鍵を保存・返却します:DER (SPKI) エンコーディング——固定のアルゴリズム識別子プレフィックスの後ろに生の鍵が続きます
- Chat XDK の
get_public_keysは、そのプレフィックスなしで生の鍵のみを返します
- Python
- TypeScript
- Rust
- Go
- C#
- Java
public_key_version を set_identity に採用してください。バージョンを比較するとき(たとえば最新の鍵を選ぶ場合)は、数値として比較してください——バージョンは長さがまちまちなミリ秒のタイムスタンプなので、辞書式比較では誤った値が選ばれます。
メッセージに対する会話鍵が見つからない
Message encrypted with key version '…' but no matching key found のようなエラーは、そのメッセージの conversation_key_version に対応する生の鍵を持っていないことを意味します。
conversation_key_change_event(ライブイベント)またはmeta.conversation_key_events(履歴)の鍵素材をextract_conversation_keysで復号する、あるいはそれらのブロブをdecrypt_eventsに含める。set_cache_keys(true)が有効なら、decrypt_eventsは各会話の最新の検証済み鍵も保持するため、以後のdecrypt_eventやencrypt_*の呼び出しでは省略できます- そのバージョンに対して会話鍵が追加されており、まだ参加者であることを確認してください(はじめに を参照)
ピアに公開鍵がない
ピアがオンボードを完了していない可能性があります。登録後、API リファレンス → Encryption keys からpublic_key、signing_public_key、identity_public_key_signature、public_key_version をロードしてください。
復号と署名
復号に失敗する
- 生の会話鍵が古い/誤っている、または鍵バージョンが間違っている
encoded_event文字列が不完全である- イベントタイプが復号可能なコンテンツとして扱える暗号化メッセージではない
署名が検証されない
検証はデフォルトで失敗クローズです(reject_unverified = true):SDK は検証されていない署名付きイベントを既に拒否しているため、ここで失敗した場合は、チェックを有効にする必要があるのではなく、検証入力が誤っていることを意味します。よくある原因:
- 送信者の署名鍵エントリが欠落または不完全(Chat XDK が必要とするすべてのフィールド——Chat XDK リファレンスを参照)
- 呼び出しに署名鍵が渡されておらず、
set_signing_keysで保存されているものもない - 送信者がバージョンをローテーションした——公開鍵を再取得してください
- 許容フロアより下の鍵バージョンは決して検証されません
- グループの鍵変更イベントでは、署名者がすでにグループを離脱している場合、その鍵はもはや提供されません——離脱したメンバーによる鍵変更 を参照してください
set_reject_unverified セッターは、このデフォルトからオプトアウトするために存在します(false。推奨されません)。以前に無効にした場合は、失敗クローズのデフォルトに戻してください。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
返信に reply_preview_validation: "Invalid" が付いている
復号された返信は reply_preview_validation("Valid" / "Invalid"。JavaScript は 'valid' / 'invalid')を持つことがあります。Invalid は、メッセージ内の引用プレビューが埋め込まれた署名済みオリジナルイベントと一致しないことを意味します——引用は信頼できないものとして扱い、検証済みオリジナルからのみ引用内容を描画してください。メッセージ自体は別途検証されており、依然として本物です。プレビューが無効でも何もスローされません。
古いイベントが恒久的に検証に失敗する
signature missing or no matching signing key や、古いイベントでの ECDSA 不一致のようなエラーは恒久的です。署名は不変であり、イベント自体から署名済みペイロードを再構築することで検証されます。そのため、異なるバイトに署名された(あるいはまったく署名されていない)イベントは、以後のロードでも毎回失敗します——リトライ、鍵の更新、API 呼び出しでは修復できません。これらのイベントはリトライ可能なエラーではなく tombstone として扱ってください。会話鍵をローテーションすれば、そこから先はクリーンで検証可能な履歴が始まります。新しいメッセージは影響を受けません。
送信ペイロードの構築
これらのミスは X Chat 暗号化に固有です(一般的な HTTP エラーではありません):状態を変更する呼び出しで API が 400 を返す
状態を変更するすべてのチャット呼び出し(会話鍵の追加やローテーション、グループの作成、メンバーの追加)は、リクエストボディにaction_signatures を必要とし、API 境界で検証されます。エントリが欠落または不正な形式(それぞれに message_id、encoded_message_event_detail、および signature、public_key_version、signature_version を持つ message_event_signature が必要)の場合、直ちに HTTP 400 problem-details レスポンスを返します。SDK の prepare メソッド(prepare_conversation_key_change、prepare_group_create、prepare_group_members_change)を使い、返されたすべての署名を送信してください——グループ作成とメンバー追加は 2 つ返します。
メディアの暗号化と復号
- 添付を参照するメッセージと同じ会話鍵(およびバージョン)を使用してください
- ダウンロードレスポンスは、
decrypt_streamを実行するまで暗号文として扱ってください - MIME タイプは復号後に推測してください。ダウンロードの
Content-Typeは多くの場合、実際の画像タイプではありません
安全なデバッグ
暗号化の失敗を調査する際は:- 会話 ID、イベント ID、鍵のバージョンのみをログに出力してください
- 平文、パスコード、秘密鍵、完全な鍵ブロブはログに出力しないでください
set_identityに渡した署名鍵バージョンが public-key レコードのpublic_key_versionと一致することを確認してください- 履歴が不完全な場合は、鍵変更メタデータがスキップされないよう、復号前にすべてのイベントページをページングしてください