암호는 튼튼했는데 주사위가 32비트였다 — Trust Wallet 확장 지갑의 예측 가능한 개인키

암호는 튼튼했는데 주사위가 32비트였다 — Trust Wallet 확장 지갑의 예측 가능한 개인키

분류: Security · 암호 · 키생성 취약(엔트로피) [정보성]

덱. Ledger의 보안 연구팀 Donjon은 Trust Wallet 브라우저 확장에서, 지갑을 만들 때 쓰는 무작위성(엔트로피)이 사실상 32비트밖에 안 된다는 결함을 발견했습니다. 그 결과 이 확장으로 만든 지갑은 주소만 알면 개인키를 즉시 계산해낼 수 있었습니다. 표준 암호 알고리즘은 하나도 깨지지 않았습니다. 깨진 것은 그 알고리즘에 넣는 “주사위”의 품질이었습니다.

리드

암호학에는 오래된 격언이 있습니다 — 사슬은 가장 약한 고리에서 끊어진다. 암호화폐 지갑에서 그 가장 약한 고리는 대개 알고리즘이 아니라, **처음 지갑을 만들 때 뽑는 난수(무작위 수)**입니다. AES가 아무리 튼튼하고 타원곡선이 아무리 안전해도, 그 모든 것의 출발점인 씨앗(seed)이 예측 가능하면 뒤에 쌓은 수학은 전부 허사가 됩니다. 이번 사례는 “암호는 수학이 아니라 그 수학에 넣는 난수의 질이 전부를 결정한다”는 명제를 가장 아프게 보여준 사건입니다.

핵심 개념 30초

  • 씨앗(seed)과 니모닉(mnemonic). 지갑을 만들면 1224개의 영어 단어(니모닉)가 나옵니다. 이 단어들은 사실 1632바이트의 무작위 씨앗을 사람이 읽을 수 있게 인코딩한 것입니다(BIP-39 표준). 이 씨앗 하나에서 모든 블록체인의 모든 키가 정해진 규칙(BIP-32/44)으로 파생됩니다. 즉 씨앗의 무작위성 품질이 지갑 전체의 안전을 결정합니다.
  • 좋은 난수 vs 나쁜 난수. 좋은 난수는 다음에 무엇이 나올지 아무도 예측할 수 없어야 합니다. 운영체제는 이런 목적의 안전한 난수 생성기를 제공합니다(iOS·안드로이드 네이티브 앱은 이걸 씁니다). 문제는 브라우저 확장이 도는 웹어셈블리(Wasm) 환경에서 이 안전한 생성기에 접근하기 어려웠다는 데서 시작됩니다.

빈틈 — 40억 개뿐인 지갑

Trust Wallet은 여러 블록체인 기능을 담은 공통 라이브러리(Trust Wallet Core)를 씁니다. 이 라이브러리를 브라우저용 Wasm으로 옮기면서, 개발자는 운영체제의 안전한 난수 생성기를 못 쓰는 상황을 우회하려고 별도의 “보안 난수 생성기”를 직접 만들어 넣었습니다. 그런데 그 자리에 들어간 것이 **메르센 트위스터(Mersenne Twister, mt19937)**였습니다. 이 생성기는 시뮬레이션·게임처럼 통계적으로 고른 난수가 필요한 곳에는 훌륭하지만, 암호용으로는 절대 쓰면 안 되는 물건입니다. 결과를 관찰하면 다음 값을 예측할 수 있기 때문입니다.

더 치명적인 것은 이 생성기가 딱 32비트짜리 씨앗 하나만 입력으로 받는다는 점이었습니다. 그 말은 이 확장이 만들어낼 수 있는 서로 다른 니모닉이 2의 32제곱, 즉 약 40억 개뿐이라는 뜻입니다. 128비트나 256비트의 진짜 무작위성이 있었다면 우주의 원자 수보다 많은 경우의 수가 나오지만, 40억 개는 요즘 컴퓨터로는 우스운 숫자입니다. 원 연구에 따르면 가능한 모든 씨앗을 만들어내는 데 평범한 컴퓨터 한 대로 몇 시간이면 충분했습니다.

메커니즘 — 주소 하나로 개인키를 되찾다 (개념적으로만)

공격의 원리는 잔인할 만큼 단순합니다(원리만, 재현 코드·도구는 싣지 않습니다). 씨앗이 40억 개뿐이니, 공격자는 가능한 모든 씨앗에서 나올 수 있는 모든 주소를 미리 계산해 거대한 표로 만들어 둡니다. 원 연구팀은 실제로 이 표를 그래픽카드 몇 장으로 생성했고, 정렬해두면 빠른 이진 탐색이 가능한 형태로 저장했습니다. 이후에는 블록체인에 공개된 실제 사용 주소 목록을 이 표와 대조하기만 하면 됩니다. 주소가 표에 있으면 그에 대응하는 씨앗과 개인키가 즉시 튀어나옵니다 — 원 연구의 실측으로는 주소 하나당 수백 밀리초 수준이었습니다.

이 속도가 왜 무서운지가 핵심입니다. 지갑이 거래를 위해 블록체인에 처음 모습을 드러내는 바로 그 순간, 공격자는 실시간으로 개인키를 계산해 자금을 빼돌릴 수 있습니다. 사용자 입장에서는 아무것도 잘못한 게 없습니다. 표준을 그대로 따랐고, 니모닉을 잘 보관했는데도, 씨앗을 뽑는 그 한 순간의 결함 때문에 지갑 전체가 처음부터 공개나 다름없었던 것입니다.

한 줄 요약. 암호 알고리즘은 하나도 안 깨졌다. 다만 그 알고리즘에 넣을 씨앗을 뽑는 주사위가 40억 면짜리였을 뿐이다.

시간선과 대응

원 분석에 따르면 결함이 담긴 코드는 2022년 4월(브라우저 확장의 Wasm 지원이 추가된 시점)에 들어갔고, 확장 자체는 그해 11월 14일 출시됐습니다. 출시 며칠 만에 약 3천만 달러 상당의 자산이 위험에 노출됐다고 원 분석은 밝힙니다. 취약점은 2022년 11월 17일 벤더의 버그바운티 프로그램(Binance Bugcrowd 경유)을 통해 보고됐고, 벤더는 나흘 뒤인 11월 21일 새로운 결함 씨앗의 생성을 막는 수정을 반영한 뒤 사용자들에게 경고하고 자금 이전을 안내했습니다. 연구팀에 따르면 2023년 3월 벤더가 제공하는 최고 등급 포상금인 10만 달러가 지급됐고, 2023년 4월 기준으로도 여전히 약 10만 달러 상당의 자금이 도난 위험에 남아 있었다고 전했습니다.

다만 이 사건의 방어 교훈은 명확합니다 — 암호용 난수는 반드시 암호학적으로 안전한 생성기(CSPRNG)에서만 뽑아야 합니다. 통계적으로 고른 난수 생성기를 “무작위처럼 보인다”는 이유로 대신 쓰는 것은, 겉보기엔 멀쩡하지만 예측 가능한 문을 다는 것과 같습니다. 특히 새로운 실행 환경(여기서는 Wasm)으로 코드를 옮길 때, 원래 환경이 공짜로 제공하던 안전한 난수를 어떻게 대체하는지가 가장 위험한 이음매가 됩니다.

왜 반복되는가 (우리 논평)

엔트로피 결함은 암호 세계의 고전적인 재발 실수입니다. 겉으로 드러나지 않기 때문입니다 — 나쁜 난수 생성기도 결과만 보면 완벽히 무작위처럼 보입니다. 알고리즘이 깨지면 학계가 요란하게 경고하지만, 난수의 품질이 낮은 것은 아무도 비명을 지르지 않아서 조용히 배포되고 조용히 쌓입니다. 우리가 앞서 다룬 CBC 패딩 오라클이 “튼튼한 암호를 감싼 약한 사용 방식”의 문제였다면, 이번 사건은 “튼튼한 암호에 넣은 약한 입력”의 문제입니다. 방향은 반대지만 뿌리는 같습니다 — 암호의 안전은 알고리즘 하나가 아니라, 그것을 둘러싼 씨앗·검증·경계 전부가 함께 결정합니다. 원 연구팀이 덧붙인 불길한 관찰, 즉 출시 이전에 만들어진 것으로 보이는 일부 취약 주소가 발견됐다는 대목은, 같은 실수가 다른 지갑 구현에도 숨어 있을 수 있음을 암시합니다.

남는 교훈

이 지갑의 한 틈은 며칠 만에 고쳐졌지만, “약한 난수” 자체는 특정 제품의 버그가 아니라 반복되는 사고방식의 결함입니다. 실행 환경을 옮길 때마다, 새 플랫폼을 지원할 때마다, “여기서 안전한 난수는 어디서 오는가”라는 질문을 놓치는 순간 이 실수는 다른 자리에서 또 나타납니다. 그래서 우리는 개별 취약점이 아니라, 암호의 출발점인 무작위성을 항상 의심하는 방법을 남깁니다.

References / 참고자료

  1. Ledger Donjon, “Funds of every wallet created with the Trust Wallet browser extension could have been stolen” — 이 글이 재구성한 원 분석. 결함의 발견 경위, 32비트 엔트로피의 원인, 영향 추정과 벤더의 대응 시간선을 다룸. https://blog.ledger.com/Funds-of-every-wallet-created-with-the-Trust-Wallet-browser-extension-could-have-been-stolen/
  2. BIP-39 / BIP-32 / BIP-44 — 니모닉·씨앗·계층적 키 파생을 정의한 표준(개념 참고).

이 글은 위 원 분석을 우리 관점에서 다시 쓰고 방어적 논평을 더한 정보성 초안입니다. 특정 문장·소스코드·개인키·니모닉 예시를 그대로 옮기지 않았으며, 작동하는 공격 재현 코드나 도구는 싣지 않았습니다. ⚠️미확인 표시 항목은 발행 전 독립 팩트체크에서 확증·정정되어야 합니다.