BIP39는 무작위 데이터를 Seed Phrase라고 부르는 복구 단어로 바꾸는 표준입니다. 지갑은 이 단어들과 선택적으로 사용하는 추가 비밀 정보인 passphrase로 시드, 즉 키 생성의 출발점이 되는 데이터를 계산합니다. 이를 통해 비트코인에 접근할 수단을 백업하지만, 단어 자체에 코인이나 결제 내역이 담기는 것은 아닙니다.
Alice는 BIP39를 사용하는 지갑을 만들고 안내에 따라 복구 단어를 안전하게 기록합니다. 나중에 휴대전화가 고장 납니다. 그렇다고 비트코인이 네트워크에서 사라진 것은 아닙니다. 결제에 서명할 키를 보관하던 기기를 잃은 것입니다. 신뢰할 수 있는 대체 기기에서 호환되는 지갑의 복구 기능을 사용할 수 있습니다. 같은 단어를 같은 순서로 넣고, passphrase를 사용했다면 그것도 동일하게 넣으면 같은 시드가 나옵니다. 이어지는 절차에서 필요한 개인 키가 다시 만들어지고, 지갑은 Bitcoin 네트워크에서 결제 내역을 찾습니다. 이는 고객 지원팀이 비밀번호를 재설정해 줄 수 있는 계정 로그인이 아닙니다. Alice가 passphrase를 사용했다면 그것도 필요하며, 이전 휴대전화의 PIN으로 대신할 수는 없습니다. 복구 후 잔액이 0이라고 해서 반드시 코인을 잃었다는 뜻은 아닙니다. 단어와 passphrase뿐 아니라 올바른 계정과 복구 설정을 선택했는지도 확인해야 합니다. 그래서 큰 금액을 보관하기 전에 복구 절차 전체를 확인해 두는 것이 좋습니다. [1] [5] [13] [14]
긴 컴퓨터 데이터 표기보다 단어가 사람이 옮겨 적고 확인하기 쉽습니다. Marek Palatinus, Pavol Rusnak, Aaron Voisine, Sean Bowe는 컴퓨터가 만든 무작위 데이터를 사람이 손으로 옮겨 적기 좋은 형태로 바꾸는 방법을 제안했습니다. 제안서의 날짜는 2013년 9월 10일이며, 명세상 상태는 Deployed입니다. 단어는 품질 좋은 무작위 입력에서 나와야 합니다. 좋아하는 문장을 바탕으로 직접 지어내서는 안 됩니다. 그러면 사람이 만든 예측 가능한 비밀에 의존하는 Brainwallet이 됩니다. Bitcoin 노드는 BIP39를 검사하지 않습니다. 노드가 검증하는 것은 거래와 블록이지, 지갑이 키를 만든 방식이 아닙니다. [1]
기록을 잘해 두어도 그 기록으로 지갑을 복구할 수 있어야 쓸모가 있습니다. 중요한 자금을 보관하기 전에, 제조사가 권장하는 복구 절차를 신뢰할 수 있는 기기에서 확인하세요. 정확한 단어 순서뿐 아니라 필요한 passphrase, 지갑 정보, 필요하다면 파생이나 서명 설정도 보관해야 합니다. 일반적인 단일 서명 지갑에서는 완전한 백업과 필요한 passphrase를 가진 사람이 원래 기기 없이도 키를 도출할 수 있습니다. Multisig에서는 추가로 필요한 키를 확보하고 정해진 서명 규칙도 따라야 합니다. 사진, 클라우드 사본, 프린터, 클립보드 기록은 비밀을 다른 사람이나 서비스에 노출할 수 있습니다. 종이와 금속에는 서로 다른 물리적 한계가 있으며, 어떤 재료도 그 자체만으로 도난을 막지는 못합니다. [9] [13] [14]
BIP39는 호환성을 위해 영어 단어 목록을 강하게 권장합니다. 다른 목록을 지원하지 않는 지갑이 많기 때문입니다. 백업을 번역하면 원래 지갑이 유지되지 않습니다. 파생 입력으로 쓰이는 것이 문구 자체이기 때문입니다. 다른 체계도 구분해야 합니다. Electrum은 자체 형식의 백업에 별도의 버전 관리 방식을 사용합니다. 단어가 비슷해 보인다고 자동으로 BIP39가 되는 것은 아닙니다. SLIP39는 자체적인 1 024개 단어 목록과 복구에 필요한 조각 수를 정하는 규칙을 갖춘 별도 형식입니다. BIP39 백업을 단순히 잘라 나눈 것이 아닙니다. 24개 단어를 여러 봉투에 나눠 넣는다고 Shamir Secret Sharing이 되지 않으며, 오히려 보호 수준과 복구 가능성을 떨어뜨릴 수 있습니다. 백업이 실제로 어떤 형식인지 항상 알아야 합니다. [1] [11] [12]
출발점은 엔트로피, 즉 길이가 ENT = 128, 160, 192, 224 또는 256비트인 무작위 데이터입니다. 여기에 원본 데이터의 SHA-256 결과에서 맨 앞 CS = ENT/32비트를 가져와 체크섬으로 붙입니다. 전체를 11비트씩 나누면 각 묶음이 단어 하나를 정합니다. 따라서 MS = (ENT+CS)/11이라는 관계에 따라 단어 수는 정확히 12, 15, 18, 21 또는 24개가 됩니다. 12개 단어는 128비트의 무작위성과 4비트의 검사 정보를 나타내므로, 132비트 전체가 독립적인 비밀인 것은 아닙니다. 24개 단어는 256+8비트입니다. 백업의 신뢰성은 단어가 얼마나 낯설어 보이는지가 아니라 난수 생성기에서 시작됩니다. [1]
11비트짜리 각 묶음은 순서가 정해진 2 048개 단어 목록에서 항목 하나를 선택합니다. 따라서 첫 번째 단어가 첫 번째 개인 키라는 뜻은 아닙니다. 모든 단어가 함께 원본 데이터와 체크섬을 기록합니다. 영어 목록에서는 앞의 네 글자만으로 단어를 구별할 수 있습니다. 하지만 이것은 모든 언어에 적용되는 규칙도, 복구할 때 단어를 마음대로 줄여 써도 된다는 지침도 아닙니다. 순서를 바꾸거나, 동의어로 대체하거나, 번역하면 입력 데이터가 달라집니다. 체크섬이 틀려지는 경우도 있고, 다른 유효한 백업이 만들어지는 경우도 있습니다. 단어와 순서를 모두 정확히 보관해야 하는 이유입니다. [1] [2]
컴퓨터는 실제로 어떤 문자를 받았는지 알아야 합니다. BIP39는 복구 문구와 passphrase 모두에 Unicode NFKD 정규화를 먼저 적용한 뒤 UTF-8로 인코딩하도록 규정합니다. NFKD는 일부 발음 구별 기호가 붙은 글자를 분해하는 등, 다르게 적힌 일부 문자를 같은 형태로 맞춥니다. 그래서 서로 다른 두 표기가 정규화 뒤에는 같은 결과가 될 수 있지만, 겉모양이 비슷하다는 이유만으로 이를 보장할 수는 없습니다. 단어의 순서, 공백, passphrase의 문자는 여전히 중요합니다. 정규화 방식을 달리하면 복구할 때 다른 시드가 도출될 수 있습니다. 참조 구현과 공개 테스트 벡터는 프로그램이 정해진 절차를 지키는지 확인하는 데 도움이 됩니다. [1] [3] [4]
PBKDF2 함수는 서로 분리된 두 입력을 받습니다. password 입력에는 실제 복구 단어가 들어갑니다. 다른 입력은 salt라고 부르는 암호학적 추가 매개변수입니다. 여기에는 문자 그대로의 문자열 “mnemonic” 뒤에 구분자 없이 passphrase를 이어 붙입니다. 복구 단어 자체를 이곳에 다시 넣는 것은 아닙니다. 두 입력 모두 NFKD로 정규화하고 UTF-8로 인코딩합니다. BIP39는 HMAC-SHA512, 2 048회의 반복, 512비트, 즉 64바이트의 출력을 규정합니다. Passphrase를 쓰지 않아도 salt는 “mnemonic”으로 남고, 빈 값이 되는 것은 passphrase뿐입니다. 이 계산은 단어를 복호화하는 과정이 아니며, 새로운 독립적인 무작위성을 만들지도 않습니다. 따라서 단어가 유출된 뒤에는 반복 계산만으로 쉽게 추측할 수 있는 passphrase를 보호할 수 없습니다. [1] [10]
BIP39의 역할은 64바이트 시드에서 끝납니다. 다음 표준인 BIP32는 보통 고정된 키 “Bitcoin seed”를 사용하는 HMAC-SHA512로 이 시드에서 마스터 개인 키와 32바이트 chain code를 도출합니다. chain code는 키와 함께 다음 키를 도출하는 데 쓰는 추가 데이터입니다. 이 두 값이 키 트리의 출발점이 됩니다. BIP44, BIP49, BIP84, BIP86 같은 규칙은 서로 다른 파생 경로와 스크립트 유형을 정합니다. 따라서 복구할 때 올바른 단어와 passphrase를 넣어도, 프로그램이 다른 계정이나 분기, 주소 유형을 찾고 있다면 잔액이 0으로 보일 수 있습니다. 검색 중 연속으로 사용되지 않은 주소를 몇 개까지 허용할지 정하는 gap limit도 중요합니다. 원래 지갑의 이름, 계정 정보, 파생 경로 또는 Output Descriptor는 단어 자체에 담기지 않은 정보를 보완할 수 있습니다. [5] [6] [7] [8] [9] [14]
Passphrase는 시드를 도출할 때 더하는 비밀 입력입니다. 기기의 PIN이 아니며, BIP39는 잘못된 passphrase를 입력했다고 알려 주지 못합니다. 다른 값을 넣어도 결과를 계산합니다. 정규화된 입력을 바꾸는 오타는 대개 다른 지갑으로 이어지므로, 그곳에서는 자신의 자금을 볼 수 없습니다. 반대로 NFKD 결과가 같은 서로 다른 표기는 동일한 시드를 도출합니다. 복구 단어와 함께 목표 지갑을 식별할 수 있는 정보를 얻은 사람은 passphrase 후보를 오프라인에서 시험할 수 있습니다. Passphrase를 쓴다면 충분히 강한 값을 선택하고, 신뢰할 수 있는 방식으로 입력하며, 별도의 믿을 만한 백업을 마련해야 합니다. 따로 보관하는 목적은 둘이 함께 도난당할 위험을 줄이는 것이지, 자신과 함께 영원히 사라질 비밀로 만드는 것이 아닙니다. [1] [13]
체크섬은 오타를 찾는 데 도움이 되지만, 백업이 누구의 것인지 또는 안전하게 만들어졌는지를 증명하지는 않습니다. 12개 단어에서는 4비트, 24개 단어에서는 8비트입니다. 따라서 해당 목록에서 균등하게 무작위로 고른 단어열이 검사를 통과할 확률은 각각 1/16과 1/256입니다. 많은 오류를 찾을 수 있지만 전부는 아니며, 체크섬이 오류를 스스로 고쳐 주지도 않습니다. 공격자는 유효한 체크섬을 가진 다른 백업을 만들 수 있습니다. 명세는 불일치할 때 경고하도록 요구하며, 단어 검사와 시드 도출 자체를 구분합니다. 따라서 체크섬이 유효하지 않다면 원래 지갑과 그 형식에 맞춰 문제를 해결해야 합니다. 실제 백업을 인터넷 검사 도구에 입력해서는 안 됩니다. [1]
단어, 체크섬, 시드
BIP39는 128비트 엔트로피에 4비트 체크섬을 붙입니다. 만들어진 132비트를 11비트씩 12개 묶음으로 나누고, 각 묶음이 목록에서 단어를 선택합니다. 복구 단어는 이후 PBKDF2-HMAC-SHA512의 password 입력이 됩니다. Salt는 문자 그대로의 접두사 “mnemonic”과 사용했다면 passphrase를 이어 붙여 만듭니다. NFKD 정규화와 UTF-8 인코딩 후 2 048회의 반복으로 512비트 시드를 도출합니다. 체크섬은 무작위성을 더하지 않습니다.
더 정확히 이해하려면 이 항목과 함께 다음도 읽어 보세요 Seed Phrase, HD Wallet, BIP39 passphrase, Trezor, Bitcoin, BIP39 checksum. 다음 항목에서도 이 글을 참조합니다 Seed Phrase, HD Wallet, Cold Storage, BIP (Bitcoin Improvement Proposal).
01BIP 39는 Bitcoin 합의의 일부인가요?+
아닙니다. 무작위성을 기록하고 시드를 도출하기 위한 지갑의 규약입니다. Bitcoin 노드는 키가 BIP 39로 만들어졌는지 몰라도 거래와 블록을 검증합니다.
0212개 또는 24개 단어로 된 문구는 모두 BIP 39와 호환되나요?+
아닙니다. 단어 수만으로는 충분하지 않습니다. 단어 목록과 순서, 체크섬, NFKD 정규화, 시드 도출 방식이 맞아야 합니다. 원래 지갑을 복구하려면 사용한 경우 올바른 passphrase와 함께 해당 파생 경로 및 스크립트 유형도 필요합니다.