Skip to main content
X Chat은 종단 간 암호화되어 있습니다. 사용자의 메시지는 평문 형태로는 오직 사용자의 기기에만 존재합니다. 이 페이지는 그 동작 방식을 설명합니다.
이 페이지는 참고용입니다. 앱을 구축하기 위해 이 지식이 반드시 필요하지는 않습니다(Chat XDK가 여기의 모든 작업을 대신 수행합니다).

전체 그림

계정 생성부터 메시지 송수신에 이르는 전체 흐름을 살펴보겠습니다.
1

계정 생성

이 단계에서 Chat XDK는 사용자의 기기에서 두 개의 키페어를 생성합니다:
  • 비밀을 수신하기 위한 아이덴티티 키페어(identity keypair)
  • 작성자임을 증명하기 위한 서명 키페어(signing keypair)
개인 키 부분은 보안 키 백업으로 전달되며, 이는 뒤에서 자세히 설명합니다. 여기서 중요한 점은 이 키들이 오직 사용자의 패스코드로만 복구 가능하다는 것입니다. X는 이를 복구할 수 없습니다.공개 키 부분은 아이덴티티 키와 서명 키를 서로 묶는 서명과 함께 public key API를 통해 X 백엔드에 게시됩니다.
2

대화 생성

사용자에게 메시지를 보내려면, 발신자는 메시지를 암호화할 대칭 키인 새로운 **대화 키(conversation key)**를 생성합니다.발신자는 X 백엔드에서 사용자의 공개 키를 가져와 서명을 검증한 후, 사용자의 아이덴티티 키로 대화 키를 암호화합니다.이것은 공개 키 암호화의 결정적 특성입니다. 누구나 사용자의 공개 키로 암호화할 수 있지만, 오직 사용자의 개인 키만이 복호화할 수 있으며, 그 키는 사용자만이 보유합니다. 따라서 X는 암호화된 사본을 저장하고 전달할 수는 있지만 결코 열어볼 수 없습니다. (사용된 정확한 방식은 용어집을 참고하세요.)왜 메시지를 사용자의 공개 키로 직접 암호화하지 않을까요? 속도 때문입니다. 공개 키 암호화는 대칭 키 암호화보다 훨씬 비용이 크므로, 키를 교환하면 이후 메시지들의 효율성이 높아집니다.
3

메시징

누군가 사용자에게 메시지를 보내면, 사용자는 아이덴티티 공개 키로 암호화된 대화 키와, 그 대화 키로 암호화된 메시지들을 받게 됩니다.사용자는 아이덴티티 개인 키로 대화 키를 복호화하고(다시 강조하지만, 이 키는 오직 사용자만 보유합니다), 얻어낸 대화 키로 메시지를 복호화합니다.이따금 여러 이유로 대화의 키가 회전됩니다(새로운 대칭 키가 공유됩니다). 따라서 각 대화 키에는 버전이 있어 참여자들이 항상 올바른 키를 사용하고 있음을 확인할 수 있습니다.
4

서명

암호화는 누구든 사용자에게 메시지를 보낼 수 있고 오직 사용자만 복호화할 수 있게 해줍니다. 서명은 어떤 의미에서 그 반대로, 사용자(그리고 오직 사용자만)가 메시지에 서명할 수 있고, 누구든 그 서명을 검증할 수 있게 해줍니다. 실무적으로 서명에는 개인 키가 필요하며, 검증에는 공개 키를 사용할 수 있습니다.X Chat에서는 모든 발신자가 자신의 메시지에 서명합니다. 서명은 누가 메시지에 서명했는지와 서명된 정확한 바이트를 모두 증명하므로, 모든 수신자는 이 메시지가 발신자가 입력한 바로 그 메시지임을 검증할 수 있습니다. 다시 말하지만, XDK가 이를 대신 처리합니다. 세부 사항은 서명 설명에서 다룹니다.

종합하기

X Chat은 세 가지 표준 암호화 도구를 조합하며, 각 도구는 자신이 잘하는 한 가지 일을 담당합니다:
  1. 대화 키는 메시지를 암호화합니다. 대칭 방식이며, 모든 메시지 및 미디어 트래픽에 충분히 빠릅니다.
  2. 아이덴티티 키페어는 다른 누구(X 포함)도 볼 수 없도록 각 참가자에게 대화 키를 전달합니다.
  3. 서명 키페어는 작성자를 증명합니다. 모든 메시지는 수신자가 검증하는 서명을 가집니다.
X는 오직 **암호문과 감싸진 키(wrapped keys)**만 전송하고 저장하며, X 자신이 열 수 있는 것은 없습니다. XDK가 암호화를 수행하고, Chat API는 키를 등록하고 암호화된 페이로드를 이동시킵니다(시작하기). 전체 등장 인물:

실제 사례

Bob과 Carol이 있는 그룹을 생성할 때 실제로 어떤 일이 일어나는지 살펴보겠습니다.
1

대화 키 생성

XDK가 새로운 랜덤 대화 키를 생성합니다. 지금까지 이 키는 오직 사용자의 기기 메모리에만 존재합니다.
2

참가자 키 조회 및 검증

앱이 X 백엔드에서 Bob과 Carol의 공개 키를 가져와 각 키의 서명을 검증합니다. 서명이 유효하지 않으면 진행을 중단합니다. 검증할 수 없는 키로는 절대 암호화하지 마세요.
3

각 참가자에게 키 감싸기

XDK는 대화 키를 세 번 감쌉니다: Bob의 아이덴티티 공개 키로, Carol의 것으로, 그리고 사용자 자신의 것으로(사용자의 다른 기기에서도 읽을 수 있도록).
4

변경 사항 서명

XDK는 정확히 이 변경 사항—그룹, 그 멤버, 감싸진 키—을 기술하는 페이로드에 서명합니다. 그룹 생성은 두 개액션 서명이 필요하며, XDK가 둘 다 생성해 줍니다.
5

게시

앱이 감싸진 사본과 서명을 X에 POST합니다. 서버는 자신이 열 수 없는 세 개의 암호화된 blob을 저장합니다. 이 과정 어디에서도 원시 대화 키가 사용자의 기기를 떠난 적이 없습니다!
6

Bob의 읽기

Bob의 XDK가 자신의 아이덴티티 개인 키로 자신의 사본을 풀고, 키 변경이 사용자로부터 온 것임을 검증한 뒤, 원시 대화 키를 보유합니다.
이것은 일회성 설정입니다. 여기서부터 모든 메시지는 동일한 두 흐름을 따릅니다: 보내기. XDK가 현재 대화 키로 메시지를 암호화하고 서명하며, 앱이 send message 엔드포인트에 둘 다 POST합니다. X는 자신이 읽을 수 없는 바이트를 저장하고 전달합니다. 받기. 암호문은 웹훅 또는 활동 스트림을 통해, 혹은 이력 조회를 위한 대화 events를 통해 도착합니다. XDK는 먼저 발신자의 서명을 검증한 뒤, 저장된 대화 키로 복호화합니다(키가 회전된 경우, key change 이벤트가 새로 감싸진 사본을 전달합니다). 검증에 실패하면 메시지는 거부됩니다. 구현 내용은 시작하기Chat XDK 레퍼런스에 있습니다.

보안 키 백업: 분산 키 저장

앞서 사용자의 개인 키는 보안 키 백업에 저장되며 오직 패스코드로만 복구할 수 있다고 말했습니다. 이제 그 동작 방식을 살펴보겠습니다. 이것이 사람들이 가장 회의적으로 여기는 부분이기 때문입니다. X가 읽을 수 없으면서 어떻게 키를 백업할 수 있을까요?

전통적 키 저장 방식의 문제점

보안 키 백업이 이를 해결하는 방식

X Chat은 오픈소스 Juicebox 프로토콜을 사용하며, 이는 **임계 비밀 공유(threshold secret sharing)**와 패스코드 보호를 결합합니다. 전체 프로토콜은 해당 사이트에 명세가 있으며, 짧게 요약하면 다음과 같습니다: 저장(계정 생성 시 한 번). XDK가 사용자의 개인 키를 여러 조각(share)으로 나누고, 이를 서로 격리된 별개의 서비스인 세 개의 realm에 분산 저장합니다. 세 realm 모두 X가 운영하므로 격리만으로는 큰 의미가 없을 것입니다. 여기서 하드웨어가 역할을 합니다. 세 realm 중 두 개는 하드웨어 보안 모듈(HSM) 내부에서 동작하며, 이는 자신의 조각을 그 누구에게도—심지어 서버 접근 권한을 가진 X 관리자에게도—내놓지 않는 변조 방지 하드웨어입니다. 조각 하나만으로는 아무것도 드러나지 않으며, 복구에는 세 realm 중 두 개의 조각이 필요하므로, 가능한 모든 복구는 최소한 하나의 HSM을 거치게 됩니다. 즉, 사용자의 키에 도달하는 소프트웨어만의 경로는 존재하지 않습니다. HSM 소프트웨어와 이를 프로비저닝한 **키 세리머니(key ceremony)**는 공개 문서화되어 있습니다. 복구(새 기기). 사용자가 패스코드를 입력하면, XDK가 각 realm에 그것을 안다는 것을 증명합니다. Juicebox 프로토콜은 패스코드가 기기를 떠나지 않고도 이것이 가능하게 합니다. 사용자를 검증한 각 realm이 자신의 키 조각을 내놓고, 세 realm 중 두 개가 응답하면 XDK가 사용자의 기기에서 키를 다시 조립합니다. 추측 제한. 각 realm은 최대 20회의 잘못된 패스코드 시도를 허용합니다. 20번째 잘못된 시도 시, 사용자의 키 조각이 해당 realm에서 삭제됩니다. 이는 HSM에 의해 하드웨어로 강제되며, 모든 무차별 대입 공격을 막아줍니다. 결과적으로: 사용자는 패스코드만으로 새 기기에서 자신의 키를 복구할 수 있고, 어떤 단일 realm도 전체 비밀을 보유하지 않으며, 하드웨어 기반 realm은 X 자신에 대해서도 그 제한을 강제합니다.
이 중 어떤 것도 사용자가 직접 구성할 필요가 없습니다. Chat XDK가 백업 클라이언트를 포함하고 있으며, realm 구성은 사용자의 공개 키 레코드와 함께 X 백엔드에서 전달됩니다. 패스코드 저장 및 잠금 해제는 Chat XDK 호출입니다. 기존 키로 초기화하기키 생성 및 등록을 참고하세요. 서버와 봇은 종종 백업을 건너뛰고 대신 내보낸 키 blob을 사용합니다. 이를 비밀번호처럼 보호하세요.

서명 설명

모든 메시지의 서명은 수신자에게 두 가지 보장을 제공합니다:
  1. 진위성(Authenticity): 발신자의 서명 개인 키 보유자가 생성한 것임
  2. 무결성(Integrity): 서명 이후 암호화된 내용이 수정되지 않았음
서명된 내용 중 어떤 것이 변경되면 검증은 실패합니다. 물론 이 보장은 서명 키의 비밀성 만큼만 강력하며, 그렇기에 키 저장이 그토록 중요합니다. 앱에서. XDK는 암호화할 때 서명하고 복호화할 때 검증합니다. 거부는 양쪽 끝에서 일어납니다. X Chat 자체가 검증할 수 없는 이벤트를 거부하고, 수신 시 XDK도 동일하게 처리하며, 이는 기본적으로 필수입니다(이를 비활성화하는 것은 권장하지 않습니다). 세부 사항은 Chat XDK에 있습니다. 서명은 인용된 콘텐츠도 포함합니다. 답장은 자신이 인용하는 원본 서명된 메시지를 원시 형태로 임베드합니다. Chat XDK가 답장을 복호화할 때, 임베드된 원본을 검증하고 인용을 그것과 비교하여, 그 결과를 reply_preview_validation(Valid / Invalid)로 보고합니다. Invalid 결과는 인용이 서명된 원본과 일치하지 않음을 의미합니다. 답장 자체는 별도로 검증되지만 인용된 자료는 신뢰할 수 없는 것으로 취급하세요. 이로써 어떤 참가자도 다른 사람에게 지어낸 말을 귀속시킬 수 없습니다.

서명된 상태 변경(액션 서명)

서명되는 것은 메시지만이 아닙니다. 대화의 모든 변경(그룹 생성, 멤버 추가, 키 회전)도 **액션 서명(action signatures)**을 포함해야 합니다. 발신자는 그 변경이 정확히 무엇을 하는지 기술하는 페이로드에 서명하며, API는 이 서명이 누락되거나 형식이 잘못된 요청을 거부합니다. XDK가 이를 대신 생성해 줍니다. 서버가 키 변경을 완전히 검증할 수 없는 이유. 서버는 원시 대화 키를 결코 보유하지 않으므로(그것이 핵심입니다), 자신이 볼 수 없는 자료에 대한 서명을 확인할 수 없습니다. 서버는 확인할 수 있는 것—서명된 설명이 요청과 일치하는지—을 확인하며, 수신자가 키 변경을 풀 때 실제 암호학적 확인을 수행합니다. 이벤트는 불변입니다. 검증에 실패한 이벤트는 영구적으로 무효입니다. 문제 해결을 참고하세요.

보안 특성

X Chat이 무엇에 대해 보호하는지, 그리고 그만큼 중요한, 무엇에 대해 보호하지 않는지 살펴봅니다.

X Chat이 보호하는 것

X Chat이 보호하지 않는 것, 그리고 그 이유


용어집


다음 단계

시작하기

키를 구현하고, 단계별로 메시지를 보내고 받기

Chat XDK 레퍼런스

암호화 SDK 메서드와 타입

소개

제품 개요 및 아키텍처

실시간 이벤트

암호화된 이벤트가 전달되는 방식