Skip to main content
이 페이지는 X Chat 암호화와 Chat XDK 특유의 문제—키, 보안 키 백업, 복호화/검증, 그리고 암호화된 전송 페이로드 구성—를 다룹니다. 웹훅, OAuth, HTTP 상태 코드, 속도 제한에 대해서는 일반 X API인증 문서를 사용하세요.

키와 보안 키 백업

잠금 해제 실패(잘못된 패스코드)

  • 패스코드가 setup에 사용된 것과 일치하는지 확인하세요
  • 시도 간에 대기하세요; realm은 잘못된 추측을 속도 제한하며 실패가 너무 많으면 복구를 잠글 수 있습니다

키 또는 아이덴티티가 설정되지 않아 암호화 또는 복호화 실패

먼저 개인 키를 로드한 다음 세션 아이덴티티—사용자 ID와 X의 레코드에 있는 public_key_version—를 설정하세요. encrypt_*prepare_* 메서드는 이를 사용해 서명합니다. 세션 아이덴티티(그리고 명시적 호출별 오버라이드) 없이 이들을 호출하는 것은 오류입니다.

로컬 공개 키가 계정에 등록된 키와 일치하지 않음

클라이언트는 종종 *“이 기기의 키가 이 계정에 등록된 키 중 하나인가?”*라는 질문에 답해야 합니다—복원이나 가져오기 이후에 올바른 public_key_version을 채택하거나, 온보딩이 이미 이루어졌는지 판단하기 위해서입니다. Chat XDK의 get_public_keys 출력을 API의 public_key 필드와 문자열로 비교하면 항상 실패합니다—같은 키라도 마찬가지인데, 두 값이 서로 다른 인코딩을 사용하기 때문입니다:
  • API는 등록 시 업로드된 그대로 키를 저장하고 반환합니다: DER(SPKI) 인코딩—고정된 알고리즘 식별자 접두사 뒤에 원시 키가 붙어 있습니다
  • Chat XDKget_public_keys는 해당 접두사 없이 원시 키만 반환합니다
같은 키의 두 가지 표기입니다. 비교하려면 양쪽을 base64로 디코딩한 뒤 API 바이트가 SDK 바이트로 끝나는지 확인하세요(양쪽이 동일한 인코딩을 가진 경우를 대비해 완전히 동일한 바이트도 일치로 간주합니다):
일치하면 해당 행의 public_key_versionset_identity에 사용하세요. 버전을 비교할 때(예: 가장 최신 키 선택) 숫자로 비교하세요—버전은 문자열 길이가 다양한 밀리초 타임스탬프이므로 사전식 비교는 잘못된 값을 고릅니다.

메시지에 대한 대화 키 누락

Message encrypted with key version '…' but no matching key found와 같은 오류는 해당 메시지의 conversation_key_version에 대한 원시 키가 없다는 뜻입니다.
  1. conversation_key_change_event(실시간 이벤트) 또는 meta.conversation_key_events(히스토리)에서 extract_conversation_keys로 키 자료를 복호화하거나, decrypt_events에 해당 blob들을 포함시키세요—set_cache_keys(true)이 활성화되면 decrypt_events가 각 대화의 최신 검증된 키도 보존하므로 이후 decrypt_eventencrypt_* 호출이 이를 생략할 수 있습니다
  2. 해당 버전에 대한 대화 키가 추가되었고 여전히 참여자인지 확인하세요(시작하기 참고)

상대방에게 공개 키가 없음

아직 온보딩을 마치지 않았을 수 있습니다. 그들이 등록한 후에 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, 권장하지 않음). 이전에 비활성화했다면, 실패 시 거부 기본값을 복원하세요:

답장이 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과 일치하는지 확인하세요
  • 불완전한 히스토리의 경우, 복호화 전에 키 변경 메타데이터가 건너뛰어지지 않도록 모든 이벤트 페이지를 페이지 조회하세요