SNS는 글을 보관했다가 맞는 사람에게 전해 줘야 합니다. 크립톤 제로(Krypton Ø)는 이 두 가지를 하면서도 글을 읽을 수 없습니다. 서버는 잠긴 상자만 옮기고, 열쇠는 폰에만 있기 때문입니다.
글을 올리면 일어나는 일
- 이 글만을 위한 새 열쇠. 내 폰의 보안 코어가 이 글에만 쓰는 새 내용 열쇠를 만듭니다.
- 글을 잠급니다. 그 열쇠로 글과 사진, 동영상을 잠급니다. 글은 먼저 정해진 길이로 채워서, 정확한 길이가 드러나지 않게 합니다.
- 읽는 사람마다 봉투 하나. 내용 열쇠를 읽는 사람 각자의 암호화 열쇠로 봉인해, Fam 목록의 한 사람마다 봉투를 하나씩 만듭니다. 나에게도 하나 만듭니다.
- 서버는 보관하고 전합니다. 우리 서버는 암호문과 봉투를 보관했다가 읽는 사람에게 넘깁니다. 어느 쪽도 열 열쇠가 없습니다.
- 읽는 사람은 자기 봉투를 엽니다. 읽는 사람의 폰이 보안 코어 안에서 자기 봉투를 열어 내용 열쇠를 꺼내고, 글을 풀어 화면에 보여 줍니다.
글과 답마다 열쇠가 따로라서, 한 글의 열쇠로 다른 글을 열 수 없습니다. 링크 미리보기도 같습니다. 미리보기는 글쓴이의 폰에서 만들어 봉인하므로, 읽는 사람의 폰은 미리보기를 보려고 그 사이트에 접속하지 않습니다.
누가 읽을지는 누가 정하나요
내 폰이 정합니다. 폰이 스스로 가진 Fam 목록대로 글을 봉인합니다. 그 목록에는 Fam 요청을 받아들였거나, 서로 QR 코드를 찍었거나, 내가 보낸 Fam 링크를 연 사람만 들어갑니다. Fam 링크는 24시간 안에 한 번만 쓸 수 있습니다.
열쇠는 어디에 있나요
개인 열쇠는 내 폰의 보안 코어에 있습니다. 보안 코어는 Rust 로 만들었고 아이폰과 안드로이드 앱이 함께 씁니다. 화면을 그리는 앱 코드조차 열쇠를 받지 못하고, 열쇠 대신 손잡이만 받습니다. 열쇠는 아이폰 키체인이나 안드로이드 키스토어에 보관되고, 백업을 타고 다른 폰으로 옮겨 가지 않습니다.
양자 컴퓨터도 생각했습니다
지금 암호문을 모아 두었다가 나중에 양자 컴퓨터로 열려는 공격자도 있습니다. 내가 고른 사람들에게 열쇠를 건네는 바깥 층은 지금 검증된 X25519 와 양자 내성 암호 ML-KEM-768 을 함께 써서, 하나를 깨는 것으로는 부족합니다. 글 자체는 XChaCha20-Poly1305 로 잠급니다. 직접 만든 암호는 쓰지 않습니다. 모두 널리 쓰이는 표준이고, Rust 라이브러리 dalek 과 RustCrypto 로 구현했습니다.
그래도 서버가 보는 것
지키는 것만큼 지키지 못하는 것을 밝히는 것도 중요합니다.
- 요청이 서버에 닿는 순간 서버는 IP 주소와 시각을 봅니다. 그 순간에는 우편함과 계정이 이어질 수 있습니다.
- 서버에는 공개 열쇠와 암호화된 되찾기 백업이 있습니다. 백업은 종이에 적은 18개 단어 없이는 열리지 않습니다.
- 통화는 보통 중계 서버를 거칩니다. 중계 서버는 두 폰의 IP 주소를 보지만 암호화된 소리는 열지 못합니다. 폰이 중계 서버에 닿지 못하면 두 폰이 바로 이어지고, 그때는 서로의 IP 주소가 보일 수 있습니다.
- 앱 화면을 캡처하거나 녹화하면 검게 나오지만, 다른 카메라로 화면을 찍는 것은 어떤 앱도 막을 수 없습니다.
그림과 함께 본 전체 설계는 보안 설계에 있습니다.