키와 보안 키 백업
잠금 해제 실패(잘못된 패스코드)
- 패스코드가
setup에 사용된 것과 일치하는지 확인하세요 - 시도 간에 대기하세요; realm은 잘못된 추측을 속도 제한하며 실패가 너무 많으면 복구를 잠글 수 있습니다
- Python
- TypeScript
- Rust
- Go
- C#
- Java
키 또는 아이덴티티가 설정되지 않아 암호화 또는 복호화 실패
먼저 개인 키를 로드한 다음 세션 아이덴티티—사용자 ID와 X의 레코드에 있는public_key_version—를 설정하세요. encrypt_* 및 prepare_* 메서드는 이를 사용해 서명합니다. 세션 아이덴티티(그리고 명시적 호출별 오버라이드) 없이 이들을 호출하는 것은 오류입니다.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
메시지에 대한 대화 키 누락
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에 해당 blob들을 포함시키세요—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문자열 - 이벤트 타입이 복호화 가능한 콘텐츠로 취급할 수 있는 암호화된 메시지가 아님
서명이 검증되지 않음
검증은 기본적으로 실패 시 거부(fail-closed) 상태입니다(reject_unverified = true): SDK가 이미 검증되지 않은 서명 이벤트를 거부하므로, 여기서의 실패는 검사를 켜야 한다는 뜻이 아니라 검증 입력이 잘못되었다는 뜻입니다. 일반적인 원인:
- 발신자에 대한 서명 키 항목이 누락되거나 불완전(Chat XDK가 요구하는 모든 필드—Chat XDK 레퍼런스 참고)
- 호출에 서명 키가 전달되지 않았고
set_signing_keys로 저장된 것도 없음 - 발신자가 버전을 순환함—공개 키를 다시 가져오세요
- 허용 최소값 아래의 키 버전은 결코 검증되지 않습니다
set_reject_unverified setter는 이 기본값에서 옵트 아웃하기 위해 존재합니다(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)를 사용하고 반환된 모든 서명을 보내세요—그룹 생성과 멤버 추가는 두 개를 반환합니다.
미디어 암호화 및 복호화
- 첨부 파일을 참조하는 메시지와 동일한 대화 키(및 버전)를 사용하세요
- 다운로드 응답을
decrypt_stream을 실행할 때까지 암호문으로 취급하세요 - MIME 타입은 복호화 후에 추론하세요; 다운로드
Content-Type은 종종 실제 이미지 타입이 아닙니다
안전한 디버깅
암호화 실패를 조사할 때:- 대화 ID, 이벤트 ID, 그리고 키 버전만 로깅하세요
- 평문, 패스코드, 개인 키, 또는 전체 키 blob은 로깅하지 마세요
set_identity에 전달된 서명 키 버전이 공개 키 레코드의public_key_version과 일치하는지 확인하세요- 불완전한 히스토리의 경우, 복호화 전에 키 변경 메타데이터가 건너뛰어지지 않도록 모든 이벤트 페이지를 페이지 조회하세요