鍵と安全な鍵バックアップ
アンロックに失敗する(無効なパスコード)
- パスコードが
setupで使用したものと一致するか確認する - 試行の間で待機する;realm は間違った推測をレート制限し、多くの失敗の後に復元をロックすることがある
- Python
- TypeScript
- Rust
- Go
- C#
- Java
鍵や identity が未設定のために暗号化または復号に失敗する
まず秘密鍵をロードし、次にセッション IDを設定します — あなたのユーザー ID と X 上のレコードのpublic_key_version です。encrypt_* および prepare_* メソッドはこの ID で署名します;セッション ID が未設定(かつ呼び出しごとの明示的な上書きもない状態)でそれらを呼び出すとエラーになります。
- 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 に対応する未加工の鍵を持っていないことを意味します。
extract_conversation_keysでconversation_key_change_event(ライブイベント)またはmeta.conversation_key_events(履歴)から鍵素材を復号する、またはこれらの blob をdecrypt_eventsに含める —set_cache_keys(true)が有効な場合、decrypt_eventsは各会話の最新の検証済み鍵も保持し、後続のdecrypt_eventとencrypt_*の呼び出しでは省略できます- そのバージョンの会話鍵が追加されていること、およびあなたがまだ参加者であることを確認する(Getting Started を参照)
ピアが公開鍵を持っていない
彼らはオンボーディングを完了していない可能性があります。彼らが登録した後、API リファレンス → Encryption keys からpublic_key、signing_public_key、identity_public_key_signature、public_key_version をロードしてください。
復号と署名
復号が失敗する
- 古いまたは間違った未加工の会話鍵、または間違った鍵バージョン
- 不完全な
encoded_event文字列 - イベントタイプが復号可能なコンテンツとして扱える暗号化メッセージではない
署名が検証されない
検証はデフォルトで fail-closed(reject_unverified = true)です: SDK はすでに検証されていない署名付きイベントを拒否しているため、ここでの失敗はチェックをオンにする必要があるという意味ではなく、検証入力が間違っていることを意味します。一般的な原因:
- 送信者の署名鍵エントリが欠落または不完全(Chat XDK に必要なすべてのフィールド — Chat XDK リファレンスを参照)
- 呼び出しに署名鍵が渡されておらず、
set_signing_keys経由で保存もされていない - 送信者がバージョンをローテーションした — 公開鍵を再取得する
- 受け入れフロアより下の鍵バージョンは決して検証されない
- グループの鍵変更イベントで、署名者がすでにそのグループを離脱していると、その鍵はもはや配信されない — 離脱したメンバーによる鍵変更 を参照
set_reject_unverified セッターは、このデフォルトからオプトアウトする(false、推奨されません)ために存在します。以前に無効化した場合は、fail-closed のデフォルトを復元してください:
- 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 呼び出しでは治せません。これらのイベントは、再試行可能なエラーではなくトゥームストーンとして扱ってください。会話鍵をローテーションすると、その時点からクリーンで検証可能な履歴が始まります;新しいメッセージには影響しません。
送信ペイロードの構築
これらのミスは 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、鍵のバージョンのみをログに記録する
- 平文、パスコード、秘密鍵、または完全な鍵 blob はログに記録しない
set_identityに渡した署名鍵バージョンが、公開鍵レコードのpublic_key_versionと一致することを確認する- 履歴が不完全な場合、復号する前に鍵変更のメタデータがスキップされないよう、すべてのイベントページをページングする