암호화폐에서의 엔트로피와 무작위성: 왜 중요한가
모든 암호화폐 개인 키, 모든 시드 문구, 그리고 여러분이 사용하는 모든 주소는 무작위 숫자에서 시작합니다. 여러분의 전체 암호화폐 자산 보안은 단 하나의 가정에 달려 있습니다. 그 숫자가 정말로 예측 불가능했다는 가정입니다. 키를 만들어낸 난수 생성기가 약하거나, 편향되어 있거나, 예측 가능했다면 자금은 도난당할 수 있습니다. 암호를 깨서가 아니라, 키를 “추측”해서 말입니다.
이 가이드는 암호학적 맥락에서 엔트로피가 무엇을 의미하는지, 난수 생성기가 어떻게 동작하는지, 역사적으로 무작위성이 실패했을 때 어떤 문제가 있었는지, 그리고 키 생성이 건전한지 어떻게 보장할 수 있는지를 설명합니다.
엔트로피란?
정보 이론에서 엔트로피는 데이터의 불확실성 또는 예측 불가능성의 정도를 측정합니다. 암호학에서는 엔트로피가 어떤 값에 포함된 “진짜 무작위성”이 몇 비트인지 정량화합니다.
256비트 개인 키는 256비트의 엔트로피를 가져야 합니다. 이는 공격자가 평균적으로 2^255번의 추측(평균적으로 탐색 공간의 절반)을 해야 찾을 수 있다는 뜻입니다. 만약 RNG 결함으로 실제 엔트로피가 32비트뿐인 키가 생성되었다면, 공격자는 약 2^31번의 추측, 즉 대략 20억 번만 시도하면 됩니다. 현대 컴퓨터라면 몇 분 만에 소진할 수 있는 수준입니다.
엔트로피 측정
엔트로피는 비트 단위로 측정합니다. 확률변수 X의 엔트로피는 다음과 같습니다:
H(X) = -sum(p(x) * log2(p(x))) for all possible values x
균일하게 무작위인 256비트 수의 경우:
- 각 비트가 0 또는 1일 확률은 0.5입니다.
- 엔트로피 = 256비트(이 크기에서 가능한 최대치).
각 비트가 1일 확률이 0.7인 편향된 생성기의 경우:
- 비트당 엔트로피 = -(0.7 * log2(0.7) + 0.3 * log2(0.3)) = 0.881비트
- 256비트의 총 엔트로피 = 225.5비트(이상적인 값보다 11.9% 낮음)
작은 편향도 많은 비트에 걸쳐 누적되며, 유효 보안 수준을 크게 떨어뜨릴 수 있습니다.
BIP-39 맥락에서의 엔트로피
| 니모닉 길이 | 엔트로피 | 보안 수준 | 10^12/초에서의 브루트포스 |
|---|---|---|---|
| 12단어 | 128비트 | 128비트 | ~10^19년 |
| 15단어 | 160비트 | 160비트 | ~10^28년 |
| 18단어 | 192비트 | 192비트 | ~10^38년 |
| 24단어 | 256비트 | 256비트 | ~10^57년 |
이 수치는 엔트로피가 정말로 균일하다는 가정 하에 성립합니다. RNG에 결함이 있다면 실제 보안 수준은 극적으로 낮아질 수 있습니다.
난수 생성기의 종류
진정한 난수 생성기(TRNG)
TRNG는 양자 수준에서 본질적으로 예측 불가능한 물리 현상을 샘플링합니다:
- 열 잡음(thermal noise) — 전자의 열적 운동으로 인해 저항에서 발생하는 무작위 전압 요동
- 샷 잡음(shot noise) — 전자 흐름의 불연속성 때문에 전류에 나타나는 무작위 변동
- 방사성 붕괴 — 개별 붕괴 사건의 발생 시점은 근본적으로 예측 불가능
- 대기 잡음(atmospheric noise) — 번개 및 기타 대기 과정에서 발생하는 무선 주파수 잡음
Ledger와 Trezor 같은 하드웨어 지갑은 칩 내장 TRNG를 사용합니다. 이들은 물리적 잡음 소스를 샘플링하고, 화이트닝(whitening) 및 헬스 테스트(health tests)를 통해 출력을 정제합니다.
장점: 물리학 기반의 진짜 무작위성; 예측할 결정적 상태가 없음.
단점: 하드웨어 의존; 잡음 소스가 열화되면 조용히 실패할 수 있음; 처리량이 제한될 수 있음.
암호학적으로 안전한 의사 난수 생성기(CSPRNG)
CSPRNG는 충분히 무작위인 시드를 입력으로 받으면, 진짜 무작위성과 구별할 수 없는 출력을 만드는 결정적 알고리즘입니다:
- Linux:
/dev/urandom(ChaCha20 또는 유사한 암호를 사용, 하드웨어 엔트로피로 시드됨) - macOS:
/dev/urandom(arc4random, 하드웨어 엔트로피로 시드됨) - Windows:
BCryptGenRandom(CNG provider) - 웹 브라우저:
crypto.getRandomValues()(OS CSPRNG에 위임) - Python:
os.urandom()또는secrets모듈 - Node.js:
crypto.randomBytes()
장점: 빠름; 연구가 충분히 이루어진 알고리즘; 모든 플랫폼에서 사용 가능.
단점: 초기 시드 엔트로피에 의존; 결정적이므로 내부 상태가 알려지면 이후 출력은 모두 예측 가능.
비암호학적 PRNG(키에 절대 사용 금지)
대부분의 프로그래밍 언어 표준 라이브러리의 random 계열 함수는 통계 시뮬레이션용이지 암호용이 아닙니다:
- Python:
random.random()(Mersenne Twister — 결정적, 624개 출력에서 상태 복원 가능) - JavaScript:
Math.random()(V8의 xorshift128+ — 예측 가능) - C:
rand()(선형 합동 생성기 — 쉽게 예측 가능) - Java:
java.util.Random(선형 합동 — 예측 가능)
이 생성기들은 엔트로피가 낮고, 주기가 짧으며, 상태가 예측 가능합니다. 이를 키 생성에 쓰는 것은 사실상 무작위성을 전혀 쓰지 않는 것과 같습니다. 이런 함수로 개인 키나 시드 문구를 절대 생성하지 마세요.
무작위성의 역사적 실패 사례
Android SecureRandom 버그(2013)
2013년 8월, Android의 SecureRandom 구현에서 치명적 결함이 발견되었습니다. 특정 Android 기기에서 Java PRNG가 제대로 시드되지 않아 여러 비트코인 지갑 앱이 예측 가능한 상태에서 개인 키를 생성했습니다. 공격자는 이를 악용해 약 55 BTC를 탈취했습니다. 이 버그는 ECDSA 서명 nonce 생성에 영향을 주었는데, 같은 nonce를 두 번 사용하면 두 서명으로부터 개인 키를 계산할 수 있습니다.
“Blockchain Bandit”(2019)
보안 연구자 Adrian Bednarek은 지갑들이 터무니없이 약한 개인 키로 생성된 사례들을 발견했습니다. 1, 2, 3 같은 키이거나, 단순한 사전 단어를 한 번 해시한 수준의 키였습니다. 어떤 공격자는 수년간 이런 주소들의 자금을 체계적으로 쓸어 담아 45,000 ETH 이상을 축적했습니다. 이 “밴딧”은 저엔트로피 키를 열거하고 잔액이 있는지 확인했을 뿐입니다.
털린 키의 예:
- 개인 키
0x0000000000000000000000000000000000000000000000000000000000000001(숫자 1) - 흔한 비밀번호와 문구에서 유도된 개인 키
Milk Sad 취약점(2023)
libbitcoin-explorer(bx) 도구의 seed 명령은 시스템 시간 32비트로 시드된 Mersenne Twister를 사용했습니다. 즉 이 도구로 생성된 모든 키는 최대 32비트 엔트로피, 약 43억 가지 경우의 수만 가졌습니다. 공격자들은 이를 브루트포스로 찾아 자금을 탈취했습니다.
Debian OpenSSL 약한 키 버그(2008)
Debian 유지관리자가 OpenSSL 난수 생성기에 엔트로피를 제공하던 코드 한 줄을 실수로 제거했습니다. 2년 동안(2006-2008) Debian 및 Ubuntu 시스템에서 생성된 모든 암호 키는 프로세스 ID로부터의 15비트 엔트로피만 갖게 되었고, 최대 32,767개의 고유 키만 만들어졌습니다. 이 기간 영향을 받은 시스템에서 생성된 모든 SSH 키, SSL 인증서, 그리고 모든 암호화폐 키는 안전하지 않았습니다.
교훈
- 검증 없이 단일 엔트로피 소스를 절대 신뢰하지 마세요.
- 작은 구현 실수도 엔트로피를 치명적으로 낮출 수 있습니다.
- 공격자들은 약한 무작위성을 적극적으로 악용합니다. 이론이 아닙니다.
- 엔트로피가 중요한 작업에는 오픈소스 및 감사된 코드가 필수입니다.
엔트로피 소스 상세
운영체제 엔트로피 풀
현대 운영체제는 여러 소스에서 공급되는 엔트로피 풀을 유지합니다:
- 인터럽트 타이밍 — 하드웨어 인터럽트(키보드, 마우스, 디스크, 네트워크) 타이밍은 예측 불가능한 입력을 제공
- 디스크 I/O 타이밍 — 디스크 읽기/쓰기의 정확한 타이밍은 기계적·전자적 요인으로 변동
- 하드웨어 RNG — 최신 CPU(Intel RDRAND, AMD)는 칩 내장 난수 생성기를 포함
- 부팅 시 엔트로피 — 일부 시스템은 재부팅 간 엔트로피를 저장함(Linux의
/var/lib/systemd/random-seed)
OS는 암호학적 프리미티브로 이 소스들을 섞어 엔트로피 풀을 만들고, 그 풀로 CSPRNG를 시드합니다. 최신 Linux 커널(5.18+)에서는 /dev/urandom이 부팅 시 충분한 엔트로피가 모일 때까지 한 번 블록한 뒤, 그 이후에는 다시는 블록하지 않습니다.
브라우저 엔트로피(crypto.getRandomValues)
SafeSeed 생성기 같은 웹 기반 도구를 사용하면 브라우저의 crypto.getRandomValues() API가 사용됩니다. 이는 운영체제의 CSPRNG에 위임합니다:
- Chrome: OS CSPRNG로 위임(BoringSSL)
- Firefox: OS CSPRNG로 위임(NSS)
- Safari: OS CSPRNG로 위임(CommonCrypto)
기본 OS가 안전하다는 전제 하에 이는 키 생성에 안전하다고 간주됩니다. 주요 우려는 OS CSPRNG가 손상될 수 있는 환경에서 실행하는 경우입니다(예: 엔트로피 소스가 부족한 가상 머신, 또는 감염된 운영체제).
하드웨어 지갑 엔트로피
하드웨어 지갑은 칩 내장 TRNG를 사용합니다:
- Ledger(보안 요소 ST33): 아날로그 잡음을 샘플링하는 ST33 칩의 TRNG를 사용. 출력은 사용 전에 NIST SP 800-90B 헬스 테스트를 통과합니다.
- Trezor: STM32 칩의 하드웨어 RNG를 사용. Trezor는 사용자가 제공한 주사위 굴림 엔트로피를 섞는 것도 지원합니다.
- Coldcard: ATECC608A 보안 요소의 TRNG와 MCU의 하드웨어 RNG를 함께 사용하고, 두 소스를 섞습니다.
주사위 굴림 엔트로피
직접 주사위를 굴리는 방식은 가장 투명한 엔트로피 생성 방법입니다:
- 공정한 6면체 주사위 1회는 log2(6) = 2.585비트의 엔트로피를 제공합니다.
- 100회 굴림은 약 258.5비트의 엔트로피를 제공하며, 24단어 시드 문구에 충분합니다.
- 사용자가 물리적으로 무작위성을 검증할 수 있습니다(공정한 주사위, 공정한 굴림, 조작 없음).
주사위 공정성 검증:
- 카지노급 정밀 주사위(모서리가 날카롭고 둥글지 않은 것)를 사용하세요.
- 단단하고 평평한 표면에서, 뒤쪽에 멈춤판(backstop)을 두고 굴리세요.
- 주사위를 “놓지” 말고 자유롭게 굴러가게 하세요.
- 각 결과를 즉시, 순서대로 기록하세요.
**SafeSeed 시드 문구 생성기**는 (주사위 굴림 결과 같은) 사용자 엔트로피를 입력해 BIP-39 시드 문구를 생성할 수 있습니다. 이를 통해 무작위성 소스를 검증하면서도 도구의 올바른 BIP-39 구현을 활용할 수 있습니다. 최대 보안을 위해 오프라인에서 도구를 사용하세요. 자세한 내용은 오프라인 키 생성 가이드를 참고하세요.
무작위성 테스트 및 검증
NIST 통계 테스트 스위트
NIST SP 800-22는 난수 생성기를 평가하기 위한 통계 테스트 묶음을 정의합니다:
- 빈도 테스트 — 0과 1의 개수가 대략 비슷한가?
- 블록 빈도 테스트 — 비트의 하위 블록들이 대략 균등하게 분포하는가?
- 런 테스트 — 동일 비트가 연속되는 구간(runs)이 기대 길이를 가지는가?
- 최장 런 테스트 — 최장 연속 구간이 기대 범위 안에 있는가?
- 행렬 랭크 테스트 — 이진 행렬의 랭크가 기대 분포를 따르는가?
- 스펙트럼 테스트 — 비트 시퀀스의 DFT가 기대 특성을 보이는가?
이 테스트들은 편향과 패턴을 탐지할 수 있지만, 생성기가 안전하다는 것을 “증명”할 수는 없습니다. 실패만 탐지할 수 있습니다.
Dieharder 테스트 스위트
원래의 Diehard 테스트에 추가 테스트들을 더한, 더 포괄적인 통계 테스트 묶음입니다. Linux에서 오픈소스로 제공됩니다.
사용자를 위한 실용적 검증
대부분의 사용자는 NIST 테스트 스위트를 실행할 수 없습니다. 대신 다음을 실용적으로 확인하세요:
- 소스 검증 — 도구가
crypto.getRandomValues(),os.urandom(), 또는 하드웨어 RNG를 사용하는가? 소스 코드를 확인하세요. - 교차 생성 테스트 — 여러 시드 문구를 생성해 매번 서로 다른지 확인하세요.
- 엔트로피 표시 — 일부 도구는 원시 엔트로피를 보여줍니다. 눈에 띄는 패턴이 없는지 확인하세요.
- 오픈소스 감사 — 도구가 오픈소스이며 감사(audit)를 받았는가?
엔트로피 소스 혼합
고보안 키 생성을 위한 모범 사례는 여러 엔트로피 소스를 섞는 것입니다:
Final Entropy = Hash(Hardware RNG output || OS CSPRNG output || User dice rolls || Timing data)
소스를 혼합하면 한 소스가 손상되거나 편향되더라도, 최소 한 소스가 충분한 엔트로피를 제공하는 한 최종 출력은 안전하게 유지됩니다. 잘 설계된 하드웨어 지갑과 키 생성 도구들이 사용하는 접근입니다.
XOR 혼합
간단한 혼합 방식 중 하나는 XOR입니다. 소스 A에서 256비트, 소스 B에서 256비트를 얻었다면:
Mixed = A XOR B
A 또는 B 중 하나라도 진짜 무작위라면 결과도 진짜 무작위입니다. 둘 다 편향되어 있더라도 서로 독립적이라면 결과는 둘 중 어느 하나보다 편향이 줄어듭니다.
해시 혼합
길이나 품질이 다른 소스들을 섞을 때는 해시로 묶어 처리합니다:
Mixed = SHA-256(Source_A || Source_B || Source_C)
해시 함수는 엔트로피 추출기 역할을 하여, 입력 형식과 무관하게 균일한 출력을 생성합니다.
다중 서명 설정에서의 엔트로피
다중 서명 지갑은 엔트로피 측면의 중복성을 제공합니다. 한 키가 약한 엔트로피로 생성되었더라도 공격자는 다른 키들도 추가로 탈취해야 합니다. 각 키를 독립적으로 생성한 2-of-3 멀티시그는 가장 약한 키가 아니라 가장 강한 키와 동등한 보안을 제공합니다.
이는 고가치 자산 보관에서 다중 서명 구성이 강력한 이유입니다.
FAQ
암호화폐에서 엔트로피란 무엇인가요?
엔트로피는 암호 키를 생성하는 데 사용되는 데이터의 무작위성 또는 예측 불가능성의 정도입니다. 암호화폐에서는 개인 키와 시드 문구의 보안이 충분한 엔트로피에 전적으로 달려 있습니다. 256비트 키는 256비트의 진짜 무작위성을 포함해야 하며, 엔트로피가 더 낮다면 키는 추측 가능해집니다.
안전한 지갑을 위해 얼마나 많은 엔트로피가 필요하나요?
12단어 BIP-39 시드 문구는 128비트 엔트로피를 제공하고, 24단어 문구는 256비트를 제공합니다. 둘 다 현재 기술로는 브루트포스 공격에 대해 안전하다고 여겨집니다. 장기 보관 및 고가치 저장의 경우, 최대의 보안 여유(margin)를 위해 256비트(24단어)를 권장합니다.
Math.random()은 암호 키 생성에 안전한가요?
절대 아닙니다. Math.random()과 같은 비암호학적 PRNG(Python의 random, C의 rand() 등)는 결정적이고 예측 가능하며 엔트로피가 낮습니다. 암호학적 키 생성에는 절대 사용하면 안 됩니다. 브라우저에서는 항상 crypto.getRandomValues(), Python에서는 os.urandom(), 또는 하드웨어 난수 생성기를 사용하세요.
임의의 숫자를 “떠올려서” 내 엔트로피를 만들 수 있나요?
아니요. 인간은 무작위 숫자를 만드는 데 악명 높게 서툽니다. 연구들은 사람이 선택한 “랜덤” 시퀀스가 보기보다 훨씬 낮은 엔트로피를 가진다는 것을 반복해서 보여줍니다. 대신 물리적 과정(주사위, 하드웨어 RNG)이나 암호학적으로 안전한 소프트웨어 RNG를 사용하세요.
내 지갑의 난수 생성기가 안전한지 어떻게 확인하나요?
지갑이 오픈소스라면 소스 코드를 확인해 CSPRNG 또는 하드웨어 TRNG를 사용하는지 검증하세요. crypto.getRandomValues(), os.urandom(), 또는 하드웨어 RNG API 호출을 찾아보면 됩니다. 하드웨어 지갑의 경우 제조사의 보안 문서와 제3자 감사 보고서를 확인하세요.
“블록체인 밴딧”은 무엇이며 엔트로피에 대해 무엇을 알려주나요?
“블록체인 밴딧”은 (숫자 1, 2, 3 같은) 약한 개인 키나 단순 비밀번호에서 유도된 키로 생성된 지갑에서 암호화폐를 체계적으로 훔친 공격자를 말합니다. 이는 공격자들이 저엔트로피 키를 적극적으로 열거하고, 발견한 자금을 쓸어 담는다는 사실을 보여줍니다. 고엔트로피 난수 생성의 중요성을 강조합니다.
하드웨어 지갑의 난수 생성기는 신뢰할 수 있나요?
하드웨어 지갑의 TRNG는 대체로 신뢰할 수 있지만, 단일 신뢰 지점(single point of trust)입니다. 최대 보안을 위해 하드웨어 RNG 출력에 사용자 제공 엔트로피(주사위 굴림)를 섞을 수 있습니다. 일부 하드웨어 지갑(Trezor, Coldcard 등)은 이런 혼합을 기본적으로 지원합니다. 이렇게 하면 하드웨어 RNG가 손상되더라도 결과 키는 안전하게 유지됩니다.
운영체제(Linux, macOS, Windows)가 키 보안에 영향을 주나요?
네. OS CSPRNG의 품질과 구현이 키 보안에 영향을 줍니다. 최신 Linux, macOS, Windows는 모두 암호학적으로 안전한 난수 생성기(/dev/urandom, arc4random, BCryptGenRandom)를 제공합니다. 하지만 2006-2008년 Debian OpenSSL 버그가 보여주듯 OS 수준 취약점이 엔트로피를 치명적으로 낮출 수 있습니다. OS를 최신 상태로 유지하고, 충분히 감사된 소프트웨어를 사용하세요.