본문 바로가기
BlockChain/BitCoin

[BitCoin] 키, 주소, 지갑

by 손정빈 2019. 4. 15.
728x90
반응형

비트코인의 키, 주소, 지갑에 대해서 알아보겠습니다.

 

우선 비트코인이 무엇인지에 대해서 간략하게 이야기해보고자 합니다.

 

비트코인이란 디지털 통화 생태계의 근간을 이루는 개념 및 기술을 아우리는 용어로 비트코인 네트워크 상에서 참가자들 간에 가치를 주고 받는 통화 단위를 가르킵니다.

 

조금 더 개발자스럽게 접근하자면 기존 '중앙'서버나 통제소가 없이 분산화된 P2P 서비스이며, '채굴'이라는 비트코인 거래가 진행되는 동안 수학문제에 대한 해답을 찾기 위해 경쟁하는 작업을 통해 중앙은행의 역할을 해결한 가상화폐 네트워크라고 생각할 수 있습니다.

 

이러한 비트코인에서 사용되는 키, 주소, 지갑에 대해서 알아보도록 하죠

 

들어가기 앞서 비트코인은 디지털 키, 비트코인 주소, 디지털 서명 등을 통해 비트코인의 소유권이 성립됩니다. 

모든 비트코인 거래에는 블록체인에 포함되기 위해 유효한 서명이 필요하며, 이러한 서명은 유효한 디지털 키가 있어야 생성 될 수 있습니다.

또한 비트코인 거래에 있어 비트코인 수취인의 공개키는 비트코인의 주소라고 불리는 디지털 지문으로 표현되며, 수표에 수취인의 이름을 적는것과 동일한 방식이라고 보면 쉽습니다.

 

개인키 / 공개키 / 비트코인 주소는 필수적으로 비트코인 내에서 사용되는 개념들이며 이해할 필요가 있습니다.

 

개인키

개인키 (private key)는 통장 비밀번호와 같은 개념이라고 생각하면 쉽습니다. 하지만 개인키를 통해 공개키, 비트코인 주소가 생성됨으로 개인키를 잃어버리게 되면 자신의 비트코인에 대한 소유권을 잃게 됩니다. 그럼으로 개인키에 대해서는 철저한 관리가 필요합니다.

 

개인 키는 무작위로 추출한 단순한 숫자로 구성되어 있으며 비트코인에서 사용되는 개인키를 생성하는 것은 1~2^256에서 선택하는 것과 같습니다.

사람이 보기 좀 더 편리하게 16진법 64자리로 표현하여 사용합니다.

  Private key : 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD

또한 개인키는 3가지 표현법(인코딩 포맷)을 가지고 있습니다.

 유형

접두부 

설명 

 Hex

없음

 64개의 16진수

  ex) 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD

 WIF

 5

 Base58Check 인코딩

  ex) 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn

 WIF-압축형

 K 또는 L

 Base58Check 인코딩, 인코딩전 접미부 0x01 추가

  ex) KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ

 


공개키

공개키는 개인키에서 파생되지만 남들에게 알려줄 수 있는 키입니다.

비트코인 거래에 있어 공개키는 타인에게 알려지는 정보이며 서명에 있어 필요한 정보입니다.

공개키는 타원곡선 곱셈 함수를 이용해서 개인키로부터 계산되며, 그 과정을 거꾸로 진행 할수 없습니다.

K = k * G ( K : 공개키, k : 개인키, G : 생성포인트 상수 )

위와 같은 계산법은 '이산로그 찾기'로도 알려져 있는 역계산법으로 K값을 안다는 가정 하에 k값을 계산하는 과정인데, 가능한 k값을 모두 대입해보는 것만큼 어렵다고 알려져 있습니다. 즉, 무차별적으로 값을 대입해서 찾는 식입니다.

 

비트코인에서는 secp256k1이라는 타원곡선을 사용하는데 아래의 함수로 정의됩니다.

 

타원곡선 암호법에 대해서는 다음에 좀 더 자세히 살펴보도록 하겠습니다.

  K = 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD * G

계산을 통해 다음과 같이 정의가 됩니다.

  K = (x, y)

   x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A

   y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB

공개키 또한 여러 표현법이 있으나 대표적으로 압축 공개키와 비압축 공개키가 주요 표현법입니다.

 

기본적인 공개키는 접두사 0x04 + X + Y로 이루어졌는데 크기가 520bit로 블록당 수백개의 거래가 증가하면서 데이터 축소가 필요해진 것입니다.

 

사실 상 공개키는 타원곡선 함수에 있는 한점이라고 할 수있습니다. 즉 x 좌표를 알면 y좌표를 알수 있다는 것이죠. 이러한 방식 때문에 공개키 포인트의 x좌표만 저장하고 y좌표를 생략하는 방식으로 256bit에 대한 공간을 줄일 수 있게 되었습니다.

 

위 타원 곡선 함수는 y^2이기 때문에 y는 제곱근이며 양수와 음수의 값이 나오게 됩니다. 즉 하나는 짝수, 하나는 홀수가 나오게 되는데 짝수의 경우 접두사에 02, 음수의 경우 03을 붙여주게 됩니다.

비트코인 주소

비트코인 주소는 공개키로부터 생성할 때 일방 암호화 해싱을 사용하여 생성 되며, '보안 해시 알고리즘(SHA)'과 'RACE Integrity Primitives Evaluation Message Digest(RIPEMD)' 알고리즘을 사용합니다. 예를 들면 SHA256이나 RIPEMD160 등이 있습니다.

  A = RIPEMD160(SHA256(K)) : K = Public 키 

공개키 K를 가지고 SHA256 해시를 산출한 후 그 결과값 RIPEMD160 해시를 산출하면 160bit(20byte) 크기의 숫자가 생성됩니다.

여기서 A는 비트코인 주소를 의미합니다.

비트코인 주소는 거의 'Base58Check'라는 인코딩을 통해서 사용자들에게 제공되는데 Base58Checksms 58개의 문자와 검사합을 이용해서 사람이 읽을 수 있는 문자로 바꿔주고 비슷한 모양의 문자를 쓰지 않음으로써 혼란을 방지하며 거래의 표기나 항목에 대한 에러가 발생하지 않도록 해줍니다.

Base64는 소문자 26개, 대문자 26개, 숫자 10개, '+', '/' 등 특수문자 2개로 구성되어 있음.

Base58은 Base64에서 0,O, l, I, +, / 등의 부호를 쓰지 않음.

 

오타나 데이터 입력 오류 등에 대한 추가 보안을 설정하기 위해 Base58의 인코딩 포맷인 Base58Check를 이용하고 있습니다. 비트코인에서 주로 사용되는 Base58Check는 내장된 오류 검사 코드를 가지고 있는데 검사합이라는 인코딩되고 있는 데이터의 끝부분에 추가되는 4바이트 크기의 중복 검사입니다. 검사합은 인코딩된 데이터의 해시로부터 생성되기 때문에 데이터 입력 및 타이핑 오류를 감지하고 방지하는데 사용 할 수 있습니다.

 

데이터를 Base58Check로 변환하기 위해서는 앞에 Version Byte를 붙여주고 Version + Data(payload)에 대해서 이중 해시를 해주게 됩니다.

 

Checksum = SHA256(SHA256(Version + Data))

 

이러한 Checksum의 앞 4byte를 뒤에 붙여주면 Base58Check로 변환이 됩니다.

 

지갑

지갑은 비트코인을 담는 것이 아니라 비트코인 거래에 사용되는 개인키를 담는 곳으로, 대개 구조화된 파일이나 간단한 데이터베이스 형태로 구현되어 있습니다. 

 

지갑에는 3가지 개념이 존재하는데 비결정적 지갑, 결정적 지갑, 계층 결정적 지갑이 존재합니다.

 

비결정적 지갑은 무작위로 서로 간의 관계성이 없는 키를 생성하는 방법입니다. 그러나 백업이나 저장에 대한 문제가 있습니다.

 

결정적 지갑은 키 간의 서로 관계성을 가지는 키를 생성하는 방법인데 예를 들어 '딸기'가 있다면 '딸기1', '딸기2' 등의 키를 생성하는 것입니다.

 

결정적 지갑은 비결정적 지갑의 단점을 보완하기 위해 랜덤하게 발생된 Common Seed 에서 단방향 Hash 함수를 통해서 개인키를 연속적으로 생성합니다.

 

개념적으로 다음과 같이 볼수 있습니다.

 

 

Hash 함수는 입력값이 같은경우 동일한 출력값을 생성하기 때문에 Common Seed만 알고 있다면 연속된 모든 개인키를 복원할수 있습니다.

 

Common Seed를 생성하기 위해 연상기호 코드 워드(Mnemonic Code Words) 가 사용됩니다.

연상기호코드란 Common seed를 생성하기 위해 사용되는 영어 단어열입니다.

예를 들어, "apple house soccer tree cake gun..." 등의 임의의 단어열입니다.

이러한 단어를 PBKDF2 함수를 사용하여 512비트의 Common Seed를 생성하는것입니다.

 

연상기호 단어를 생성하는 과정은 다음과 같습니다.

 

1. 128~256 비트의 random 값 A 생성

2. SHA256(A) 값의 첫 몇비트를 check sum으로 생성

3. check sum을 A 값의 끝부분에 추가

4. A를 11비트로 나누어 24개의 인덱스를 생성하고, 미리 정해진 2048개의 단어로 구성된 배열의 인덱스로 사용하여 단어열 생성

 

이 과정을 그림으로 표현해보면 다음과 같습니다.

 

 

 

즉, Checksum이 포함된 Random 값을 11비트로 나누어 각각의 인덱스를 생성해내고, 2048개의 단어가 포함된 배열에서 해당 인덱스에 해당하는 단어를 가져와 단어열을 생성하는 것입니다.

 

연상기호 코드의 엔트로피와 단어길이는 다음과 같이 정의되어 있습니다.

예를 들어 Random 값이 128비트인 경우 체크섬은 해쉬값의 상위 4비트를 가져오며, random값에 4비트를 추가한 132비트를 11로 나누게 되어 단어길이는 12가 됩니다.

 

 엔트로피(비트)

 체크섬(비트)

 엔트로피+체크섬

 단어 길이

 128

 4

 132

 12

 160

 5

 165

 15

 192

 6

 198

 18

 224

 7

 231

 21

 256

 8

 264

 24

 

연상기호 코드는 BIP39에 정의되어 있습니다. 

( https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki )

 

여기서 한층 더 나아가 계층 결정적 지갑은 키들에 계층을 만들어 놓은 것입니다. 

 

계층결정적 지갑(Hierarchical Deterministic wallet) 혹은 HD 지갑이라 하는것으로 BIP0032에서 규정하고 있습니다.

계층 결정적 지갑은 트리 구조에서 생성된 키를 담고 있으며, 부모키가 자식키열을 만들어낼수 있고, 각각의 자식키가 손자키열을 만들어낼수 있습니다.

 

상위 계층의 키를 가지고 하위 계층의 키를 제어할 수 있지만, 역으로 불가능합니다.

 

HD지갑은 128,256,512비트 크기의 Root seed로부터 만들어지며, HMAC-SHA512 알고리즘을 통해 마스터 개인키 마스터 체인코드를 생성합니다.

 

Root seed를 생성하는 과정에는 결정적 지갑에서 설명되고 있는 연상기호 코드 워드가 사용됩니다.

이와같이 HD 지갑은 계층적으로 키를 생성하여 매 거래마다 새로운 주소를 생성하여 거래에 사용할수 있도록 하여 익명성을 보장합니다.

 

반응형

'BlockChain > BitCoin' 카테고리의 다른 글

[BitCoin] 블룸 필터  (0) 2019.05.02
[BitCoin] 타원 곡선 암호화  (0) 2019.05.02
[BitCoin] 단순지불검증(SPV) 노드  (0) 2019.04.16
[BitCoin] 비트코인 네트워크  (0) 2019.04.16
[BitCoin] 비트코인내에서의 거래  (0) 2019.04.16

댓글