12개 단어의 마법
메타마스크를 처음 설치할 때 받는 12개의 영어 단어. "이걸 절대 잃어버리면 안 됩니다"라는 경고와 함께 말이죠. 그런데 의문이 들지 않으셨나요? 왜 복잡한 개인키 대신 army, battle, creek 같은 평범한 단어 12개를 외우라는 걸까요?
전통적인 방식에서는 개인키를 직접 관리했습니다. 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb처럼 읽기도 어렵고 외우기는 더더욱 불가능한 16진수 문자열을 말이죠. 하지만 HD 지갑 방식은 다릅니다. 단어 12개면 수천 개의 개인키를 관리할 수 있습니다.
이 글에서는 니모닉이라는 이름의 12개 단어가 어떻게 생성되고, 어떻게 여러 개인키로 변환되며, 왜 이것만 지키면 모든 자산을 안전하게 보관할 수 있는지를 파헤쳐보겠습니다.
니모닉이 뭔가요?
니모닉(Mnemonic)은 '기억술'이라는 뜻입니다. 암호화폐에서는 BIP-39 표준에 따라 생성된 12개 또는 24개의 단어를 의미하죠. 이 단어들은 복잡한 숫자를 사람이 기억하기 쉬운 형태로 변환한 것입니다.
BIP-39는 Bitcoin Improvement Proposal 39번의 약자로, 2013년에 제안된 표준입니다. 이전에는 개인키를 직접 백업해야 했지만, BIP-39 이후로는 누구나 쉽게 지갑을 백업하고 복구할 수 있게 되었습니다.
왜 단어로 표현할까요? 10110101... 같은 이진수나 A7F2B3... 같은 16진수를 외우는 건 거의 불가능하기 때문입니다. 하지만 army battle creek... 같은 단어는 종이에 적어두거나 암기하기 훨씬 쉽죠. 이것이 바로 사람 친화적 설계의 핵심입니다.
무작위 숫자 생성 (엔트로피)
니모닉 생성의 첫 단계는 완전히 무작위인 숫자를 만드는 것입니다. 이를 엔트로피(Entropy)라고 부릅니다.
12개 단어를 생성하려면 128비트의 무작위 데이터가 필요합니다. 24개 단어는 256비트죠. 128비트는 (2^{128})가지의 조합, 즉 약 340억의 1조배에 달하는 경우의 수입니다. 우주에 있는 원자보다 많은 숫자예요.
진정한 무작위성이 중요한 이유는 예측 가능한 패턴이 있으면 해커가 추측할 수 있기 때문입니다. 그래서 지갑 생성 시 컴퓨터의 하드웨어 난수 생성기나 마우스 움직임, 키보드 입력 같은 물리적 무작위성을 활용합니다.
체크섬 추가
128비트를 생성한 후 바로 단어로 변환하지 않습니다. 오타 방지를 위한 체크섬을 추가하죠.
SHA-256 해시 함수로 128비트를 해시하고, 그 결과의 앞 4비트를 가져와 원래 128비트 뒤에 붙입니다. 그러면 총 132비트가 되죠. 이 과정을 통해 단어를 잘못 적었을 때 복구 시 에러를 감지할 수 있습니다.
실제로 니모닉을 복구할 때 "Invalid mnemonic" 에러가 뜨는 경우가 있는데, 이게 바로 체크섬이 맞지 않아서입니다.
2048개 단어 사전에서 선택
132비트를 11비트씩 잘라서 총 12개 그룹을 만듭니다. 11비트는 (2^{11} = 2048)가지 조합이 나오죠. BIP-39는 정확히 2048개의 단어 목록을 정의하고 있습니다.
예를 들어 첫 11비트가 00000000001이면 1번째 단어인 abandon을, 11111111111이면 2048번째 단어인 zoo를 선택합니다.
128비트 엔트로피 + 4비트 체크섬 = 132비트
132비트 ÷ 11비트 = 12개 그룹
각 그룹 → 2048개 단어 중 1개 선택BIP-39 단어 목록의 특징은 명확합니다. 모든 단어는 처음 4글자만으로 구분 가능하고, 철자가 비슷한 단어는 피했으며, 영어뿐만 아니라 한국어, 일본어 등 여러 언어 버전이 있습니다.
니모닉 ≠ 개인키
여기서 정말 중요한 개념을 짚고 넘어가야 합니다. 니모닉은 개인키가 아닙니다.
니모닉은 마스터 씨앗(Master Seed)입니다. 씨앗 하나에서 나무가 자라나듯, 니모닉 하나에서 무한대의 개인키를 생성할 수 있습니다. 이것이 HD(Hierarchical Deterministic) 지갑의 핵심이죠.
메타마스크에서 계정 1, 계정 2, 계정 3을 만들 수 있는 이유가 바로 이겁니다. 각 계정마다 다른 개인키를 갖지만, 모두 같은 니모닉에서 파생된 것입니다.
마스터 시드 생성
니모닉 12개 단어를 실제 암호화에 사용할 수 있는 형태로 변환하는 과정이 필요합니다. 여기서 PBKDF2라는 키 유도 함수를 사용합니다.
PBKDF2는 Password-Based Key Derivation Function 2의 약자로, 비밀번호처럼 약한 입력값을 강력한 암호화 키로 변환하는 함수입니다. 이 과정에서 2048번의 반복 연산을 수행하는데, 이유가 있습니다.
만약 해커가 무차별 대입 공격으로 니모닉을 찾으려 한다면, 각 시도마다 2048번의 연산을 해야 하므로 공격 속도가 2048배 느려집니다. 정상적인 사용자는 한 번만 계산하면 되지만, 해커는 수십억 번 시도해야 하니 시간이 기하급수적으로 늘어나는 거죠.
# 의사 코드
mnemonic = "army battle creek dog..."
passphrase = "" # 선택사항
seed = PBKDF2(
password=mnemonic,
salt="mnemonic" + passphrase,
iterations=2048,
hash_function=SHA512
)
# 결과: 512비트(64바이트) 마스터 시드
여기서 패스프레이즈를 추가할 수 있습니다. 같은 니모닉이라도 패스프레이즈가 다르면 완전히 다른 지갑이 생성되죠. 일종의 25번째 단어라고 볼 수 있습니다.
마스터 개인키와 체인 코드 분리
512비트의 마스터 시드를 반으로 나눕니다.
- 앞 256비트 → 마스터 개인키 (Master Private Key)
- 뒤 256비트 → 체인 코드 (Chain Code)
마스터 개인키는 실제로 트랜잭션을 서명할 때 사용하는 키의 시작점입니다. 체인 코드는... 잠깐, 이게 뭘까요? 이 부분에서 많은 분들이 궁금해하십니다.
여러 개인키 생성 원리
HD 지갑의 핵심은 경로(Path) 구조입니다. 메타마스크에서 사용하는 기본 경로는 m/44'/60'/0'/0/0입니다.
m: 마스터
44': BIP-44 표준
60': 이더리움 (각 코인마다 번호가 다름)
0': 계정 그룹
0: 외부 체인 (수신 주소)
0: 주소 인덱스새 계정을 만들 때마다 마지막 숫자만 바뀝니다. m/44'/60'/0'/0/1, m/44'/60'/0'/0/2... 이렇게 말이죠.
실제로 제가 프로젝트에서 다중 계정 기능을 구현할 때 이 원리를 활용했습니다. 사용자가 "새 계정 추가" 버튼을 누르면 내부적으로는 인덱스만 1씩 증가시켜서 새 개인키를 생성하는 거죠.
// ethers.js 예시
const mnemonic = "army battle creek...";
const wallet = ethers.Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/0`);
const wallet2 = ethers.Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/1`);
// 두 지갑은 완전히 다른 주소와 개인키를 가짐
체인 코드의 진짜 역할
"체인 코드도 1개인데 왜 필요한가?" 이 질문에 대한 답이 HD 지갑의 가장 중요한 보안 메커니즘입니다.
만약 마스터 개인키만으로 자식 키를 생성한다면, 누군가 자식 개인키 하나를 얻으면 역계산으로 마스터 개인키를 추론할 수 있습니다. 개인키들 사이에 단순한 수학적 관계가 있기 때문이죠.
하지만 체인 코드를 추가하면 이야기가 달라집니다. 각 자식 키를 생성할 때 HMAC-SHA512라는 일방향 함수를 사용하는데, 여기에 체인 코드가 비밀 키로 들어갑니다.
child_key = HMAC-SHA512(
key=chain_code,
message=parent_key + index
)HMAC의 특징은 결과값에서 입력값을 역추론할 수 없다는 것입니다. 즉, 자식 개인키를 100개 알아도 마스터 개인키나 체인 코드를 알아낼 방법이 없습니다.
이것이 바로 확장 공개키(Extended Public Key) 개념을 가능하게 만듭니다. 체인 코드와 공개키만 있으면 개인키 없이도 자식 공개키들을 생성할 수 있죠. 이커머스에서 매 거래마다 새 주소를 생성해야 할 때 유용합니다.
사용자가 보는 것 vs 내부 작동
메타마스크를 설치하면 니모닉 12단어만 보여줍니다. 마스터 개인키나 체인 코드는 화면에 나타나지 않죠.
왜일까요? 사용자가 관리해야 할 정보를 최소화하기 위해서입니다. 니모닉만 안전하게 보관하면 나머지는 모두 재계산할 수 있으니까요.
내부에서는 이런 과정이 자동으로 진행됩니다:
- 니모닉 → PBKDF2 → 512비트 시드
- 시드 → 마스터 개인키 + 체인 코드
- 경로에 따라 → 자식 개인키들 생성
- 개인키 → 공개키 → 주소
사용자는 "계정 추가" 버튼만 누르면 되고, 복잡한 암호화 과정은 지갑 소프트웨어가 처리합니다.
지갑 복구 프로세스
휴대폰을 잃어버렸다고 가정해봅시다. 새 기기에 메타마스크를 설치하고 "지갑 복구" 옵션을 선택한 후 니모닉 12단어를 입력합니다.
마법처럼 모든 계정과 잔액이 그대로 나타나죠. 왜 그럴까요?
니모닉이 같으면 마스터 시드가 같고, 마스터 시드가 같으면 모든 자식 개인키가 동일하게 재생성됩니다. 결정론적(Deterministic)이라는 말이 바로 이겁니다. 같은 입력은 항상 같은 출력을 만듭니다.
실제로 제가 테스트할 때 같은 니모닉으로 여러 기기에서 복구해봤는데, 계정 순서, 주소, 모든 것이 정확히 일치했습니다. 블록체인에 기록된 트랜잭션 내역도 당연히 그대로 보입니다.
개별 개인키 추출
때로는 특정 계정의 개인키만 필요할 수 있습니다. 예를 들어 하드웨어 월렛으로 이동하거나, 다른 지갑 소프트웨어를 사용할 때죠.
메타마스크에서는 "계정 세부 정보" → "개인 키 내보내기"를 통해 확인할 수 있습니다. 하지만 이 부분에서 주의할 점은, 개별 개인키는 그 계정 하나만 제어한다는 것입니다. 니모닉처럼 모든 계정을 복구할 수 없습니다.
// web3.js 예시
const account = web3.eth.accounts.privateKeyToAccount(
'0x4c0883a69102937d6231471b5dbb6204fe512961708279...'
);
니모닉 노출 = 모든 것 노출
보안 측면에서 가장 중요한 사실은 니모닉이 노출되면 모든 계정이 위험하다는 것입니다.
개별 개인키 하나가 유출되면 그 계정만 털립니다. 하지만 니모닉이 유출되면? 현재 사용 중인 모든 계정, 심지어 아직 생성하지 않은 미래의 계정까지 해커가 접근할 수 있습니다.
그래서 니모닉은 디지털 형태로 저장하면 안 됩니다. 클라우드, 이메일, 메신저, 어디에도 올리면 안 됩니다.
안전한 백업 방법
실무에서 추천하는 방법들입니다:
- 종이에 적기: 가장 기본적이지만 효과적입니다. 여러 장 복사해서 다른 장소에 보관하세요
- 철판에 새기기: 화재나 수해에도 견딜 수 있는 스틸 플레이트 제품들이 있습니다
- 분산 보관: 12개 단어를 2개 그룹으로 나눠 다른 장소에 보관 (6+6)
절대 하면 안 되는 것들:
- 사진 찍어서 갤러리 저장 (클라우드 자동 백업 위험)
- 노트 앱에 입력 (해킹, 악성코드 위험)
- 이메일로 자신에게 전송 (서버 해킹 위험)
- 카카오톡 나와의 채팅 (서버에 저장됨)
이 부분에서 실제로 많은 사람들이 실수합니다. 편의성을 위해 디지털 저장을 선택했다가 큰 손해를 보는 경우가 빈번합니다.
패스프레이즈 추가
BIP-39는 선택적으로 패스프레이즈를 추가할 수 있습니다. 니모닉 12단어에 더해 자신만 아는 암호를 추가하는 거죠.
예를 들어 니모닉이 army battle creek...이고 패스프레이즈를 mySecret123로 설정하면, 같은 니모닉이라도 완전히 다른 지갑이 생성됩니다.
니모닉 + 패스프레이즈 "" = 지갑 A
니모닉 + 패스프레이즈 "mySecret123" = 지갑 B (전혀 다른 주소)이 방법의 장점은 니모닉이 유출되어도 패스프레이즈를 모르면 자금에 접근할 수 없다는 것입니다. 하지만 단점도 명확합니다. 패스프레이즈를 잊어버리면 영원히 복구할 수 없습니다.
인포그래픽: 니모닉 → 개인키까지의 여정
전체 과정을 정리하면 이렇습니다:
1. 난수 생성 (엔트로피)
128비트 무작위 숫자
↓
2. 체크섬 추가
SHA-256 해시 → 앞 4비트
↓
3. 단어 변환
132비트 ÷ 11비트 = 12개 단어
↓
4. 마스터 시드 생성
PBKDF2(니모닉, 2048회 반복)
↓
5. 마스터 키 분리
256비트 개인키 + 256비트 체인 코드
↓
6. 자식 키 생성
HMAC(체인 코드, 부모 키 + 인덱스)
↓
7. 개별 계정
각 경로마다 고유한 개인키사용자 관점에서는 "니모닉 12단어 → 여러 계정"으로 단순하지만, 기술적으로는 7단계의 복잡한 암호화 과정이 숨어있습니다.
HD 지갑의 혁신성
HD 지갑이 등장하기 전에는 각 주소마다 개인키를 따로 백업해야 했습니다. 주소 10개를 사용하면 개인키 10개를 관리해야 했죠.
하지만 BIP-39와 BIP-32 덕분에 이제는 단어 12개만 기억하면 됩니다. 수천 개의 계정을 사용해도 니모닉 하나로 모두 복구 가능합니다.
이것이 메타마스크, 트러스트월렛, 레저, 트레저 등 모든 주요 지갑이 HD 지갑 방식을 채택한 이유입니다. 보안과 편의성을 동시에 달성했기 때문이죠.
사용자가 기억해야 할 것
결국 사용자가 반드시 기억하고 보호해야 할 것은 딱 하나입니다. 니모닉 12단어.
이 12개 단어만 안전하게 보관하면:
- 기기를 잃어버려도 복구 가능
- 여러 기기에서 동시 사용 가능
- 새 계정 무한정 생성 가능
- 평생 동안 같은 지갑 사용 가능
반대로 이 12개 단어가 노출되면:
- 모든 자산 즉시 탈취 위험
- 과거, 현재, 미래 계정 모두 위험
- 복구 불가능
암호화폐 보안은 결국 니모닉 보안입니다. 아무리 복잡한 스마트 컨트랙트를 다루고, 아무리 많은 DeFi 프로토콜에 투자해도, 니모닉 관리를 실수하면 한순간에 모든 것을 잃을 수 있습니다.
지금 당장 여러분의 니모닉이 어디에 어떻게 보관되어 있는지 확인해보세요. 디지털 형태로 저장되어 있다면, 오늘이 종이에 옮겨 적을 마지막 기회일 수 있습니다.
참고 자료
이 글에서 다룬 암호화 기술들의 공식 문서 및 참고 사이트입니다.
BIP 표준 문서
BIP-39 (Mnemonic Code for Generating Deterministic Keys)
- GitHub 공식 문서: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
- 니모닉 코드 생성 표준 정의
- 2048개 단어 목록 및 생성 알고리즘
BIP-32 (Hierarchical Deterministic Wallets)
- GitHub 공식 문서: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
- HD 지갑의 핵심 구조 정의
- 마스터 키에서 자식 키 파생 알고리즘
BIP-44 (Multi-Account Hierarchy for Deterministic Wallets)
- GitHub 공식 문서: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
- 경로(Path) 구조 표준화: m/44'/60'/0'/0/0
- 다중 코인 지원 체계
암호화 함수 표준
SHA-256 (Secure Hash Algorithm 256-bit)
- NIST 공식 문서: https://csrc.nist.gov/publications/detail/fips/180/4/final
- 미국 국립표준기술연구소(NIST) FIPS 180-4
- 체크섬 생성 및 해시 알고리즘
PBKDF2 (Password-Based Key Derivation Function 2)
- RFC 2898: https://datatracker.ietf.org/doc/html/rfc2898
- IETF(Internet Engineering Task Force) 공식 표준
- 니모닉에서 마스터 시드 생성
HMAC-SHA512 (Hash-based Message Authentication Code)
- RFC 2104: https://datatracker.ietf.org/doc/html/rfc2104
- 일방향 해시 기반 메시지 인증
- 자식 키 생성 시 사용
실습 도구
BIP39 Mnemonic Code Converter
- Ian Coleman 도구: https://iancoleman.io/bip39/
- 니모닉 생성 및 키 파생 과정 시각화
- 주의: 실제 지갑 생성 시 오프라인에서 사용 권장
BIP39 한국어 단어 목록
- GitHub: https://github.com/bitcoin/bips/blob/master/bip-0039/korean.txt
- 2048개 한국어 니모닉 단어
추가 학습 자료
Ethereum HD Wallet 구현
- Ethers.js 문서: https://docs.ethers.org/v5/api/utils/hdnode/
- JavaScript에서 HD 지갑 구현 방법
Web3 Wallet Integration
- WalletConnect 문서: https://docs.walletconnect.com/
- MetaMask 개발자 문서: https://docs.metamask.io/
'Blockchain' 카테고리의 다른 글
| ERC 토큰 표준 둘러보기 (0) | 2026.02.07 |
|---|---|
| EIP-6963 2편: DApp에 지갑연결 구현하기 (0) | 2026.01.27 |
| EIP-6963 1편: 지갑 연결의 새로운 표준 EIP-6963 (0) | 2026.01.27 |
| Ethers.js 없이 ERC-20 토큰 단위 변환하기 (0) | 2026.01.26 |
| 블록체인 도메인 개발자가 JSON-RPC를 꼭 알아야 하는 이유 (0) | 2026.01.26 |