3_상식보충.md 14 KB

먼저 알아두고 가야할 개념

개요

비트코인은 보안과 관련된 컴퓨터 과학적 지식의 총집합 이라해도 과언이 아니다. 이와 관련된 전문적인 지식들의 대부분은 관련된 파트에서 알려주겠지만 몇몇가지개념은 모든분야에 거쳐 상식적으로 쓰이기때문에 미리 알고 넘어가야할 필요가 있다. 처음에는 이해하기 힘들지도 모르나 알고나면 간단한 개념이기에 (작동원리를 이해할 필요는 없다.) 시간적 여유를 두고 곰곰히 생각해 볼것을 권장한다.

해시함수

우리손가락에 있는 지문에 대해서 생각해보자. 일반적으로 모든 사람은 각기 고유한 지문을 가지고 있다고 한다. 또한 A라는 사람과 B라는사람이 지문이 같을 확률은 약 640억분의 1이라고 한다. 지구상의 인구가 640억명을 넘어가면 한명쯤은 나와 같은 지문을가진 사람이 나타날 수 있지만 현실에서 지구상의 인구는 70억명밖에 안되고 70억명중에 나와 같은 지문을 가진사람이 있을 확률은 매우 적기 때문에 사실상 나의 지문은 나만의 것이라고 해도좋으며 많은 정부기관에서 개개인의 신원을 특정하는데 부터 스마트폰의 소유자 확인까지 지문을 많이 사용한다. 그럼 컴퓨터 파일상에도 지문을 만들 수 없을까? 라는발상에서 나온 것이 해시함수이다.

정의적으로 해시함수는 임의의 길이를 가지는 임의의 데이터를 고정된 길이의 데이터로 바꿔주는 함수를 총칭한다. 무슨 의미냐 하면 워드파일부터 온라인게임 통신 데이터까지 우리가 컴퓨터에서 다루는 모든것은 0과 1로 이루어진 데이터 덩어리 이며 이 데이터 덩어리를 해시함수에 넣고 돌리면 고정된 개수의 0과 1을 내보내 준다는 것이다. 예시를 들어보자면 SHA2라는 해시함수에다 "Hello World"라는 문자열을 입력하면 대략 다음과 같은 모습을 보이며 출력값으로 보이는 저 문자열은 언제나 일정한 길이를 가진다는 것이다.

​```flow
st=>start: "Hello World"
io=>inputoutput: SHA2
e=>end: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

st->io->e->
​```

다만 이게 어떻게 사람의지문과 연결되는 것일까? SHA2의 경우 데이터를 입력받았을때 입력받은 데이터를 256개의 0과 1로 바꾸어준다. 여기서 핵심은 이 256개의 0과 1은 총 2^256가지의 경우를 표현해 낼 수 있는데 워낙 표현해낼 수 있는 가능성이 많다보니 서로 다른 두 데이터가 같은 해시값을 가질 확률이 1/2^256 밖에 안된다는 것이다. 우주를 나이(137억년)를 나노초단위로 표현할때 10^24 단위의 숫자가 사용되고 2^256이 10^77 단위의 숫자가 사용된다는 점과 지구상의 컴퓨터로 일일히 비교해봐서 서로다른 데이터가 같은 해시값을 가지는 경우를 찾으려면 우주의 나이가 넘는 시간이 필요하다는점을 생각할때 해시값이 같은 서로다른 두 데이터를 노가다로 찾는것은 사실상 불가능 하고 수학적으로 찾기에는 애초에 수학적으로 찾을 수 없게 설계해 놓았기에 어떤 데이터의 해시값은 그 데이터 고유의 지문이라 할 수 있는것이다.

그럼 이 컴퓨터상의 지문인 해시함수는 주로 어떻게 사용될까? 많은 사용법이 알려져있지만 그 중 비트코인과 관련된 사용법을 말해보자면 그 중 하나는 바로 데이터 검증이다. 생각해보자, 현실세계에서 많은 정부기관이 국민들의 지문데이터를 보관해둔다. 그리고 이렇게 보관된 지문데이터로 범죄현장에서 지문으로 범인 판별부터 해외로 입출국시 본인인증까지 다양한 곳에서 실제 본인인지에 대해 검증해낸다. 해시값도 마찬가지이다. 인터넷에 파일을 다운로드할때 데이터 원본과 해당 데이터의 해시값을 같이 다운로드하면 다운받은 뒤 데이터의 해시값을 구해 다운받은 해시값과 비교해보면 이 데이터가 업로더가 의도한 파일과 같은 파일인지 아님 무언가 변조된 파일인지 알아낼 수 있는것이다. 이런 방법으로 해시함수를 통해 우리는 어떤 데이터가 어떠한 변조도 없는 데이터인지 판별해낼 수 있다.

또 다른 비트코인에서 해시함수의 사용방법으로는 작업증명(POW:Proof Of Work) 이라는 사용방식이 있다. 위에서 말했다시피 SHA2의 결과값으로는 우리가 예측할수 없는 256개의 0과 1이 나온다. 이러한 256개의 0과 1은 수적인 관점으로보면 2진수로 표현된 어떤 큰 자연수 라고 할 수있는데, 이 큰 자연수가 1,024=2^10보다 작은 수가 나올 확률은 2^10/2^256 = 1/2^246 이라고 할 수 있다. 즉, 컴퓨터가 1,024보다 작은 어떤 자연수를 노가다 뛰면서 발견할 확률은 1/2^246이며 2^246번정도 연산하면 하나쯤은 발견해 낼 수 있다는 것이다. 만약 어떤 컴퓨터가 해시값을 구해봤더니 1,024보다 작은 어떤 값을 발견해냈다면 우리는 대략 이 컴퓨터가 (엄청 운이 좋은경우가 아니면) 2^246번의 연산을 해봤음을 추측할 수 있고 이를 비트코인에서는 POW라고 부른다.

서로 다른 두 데이터 간에 같은 해시 값이 나오면 어떻게 되나요?

엄청나게 적은 확률이긴 하지만 그래도 서로다른 두 데이터간에 같은 해시값이 나올 가능성은 존재한다. 이런 상황을 해시충돌이라는 용어로 표현한며 이는 서로다른 두 데이터가 같은 데이터라고 주장해 버릴수가 있어 데이터 검증목적으로 사용되는 모든 해시함수에게 악몽같은 상황이다. 물론 악몽이라 불리는만큼 애초에 이런일이 발생하지 않게 함수를 설계하기는 하지만 그래도 시간이 지나면서 해시충돌을 의도적으로 찾아낼 수 있는 방법이 발견되가고 있다. 대표적인 경우가 md5와 SHA1이라는 해시함수이다. 먼저 md5의 경우 1991년 개발되어 처음나올당시 준수한 성능을 자랑했지만 시간이 지나고 컴퓨터 성능이 비약적으로 좋아지면서 2017년 현재와서는 스마트폰만으로도 1분 안에 A라는 데이터와 해시충돌이 발생하는 B라는 데이터를 찾아낼 수 있다. 또 SHA1의 경우 2017년 2월 구글이 공개한 방법을 사용하면 특정 데이터에 한해서 본래 12,000,000개의 그래픽카드를 병렬로 1년동안 쉬지않고 탐색해봐야 해시충돌이 일어나는 데이터를 찾아낼 수 있어야 하는데, 단 110개의 그래픽을 1년동안 쉬지않고 돌리면 해시충돌을 찾아낼 수 있게 되었다. SHA2는 아직 그 어떤 알려진 방법도 존재하지 않고 SHA1보다 훨씬 더 많은 연산량을 요구하긴 하지만 시간이 지나면 SHA2도 쉽게 해시충돌을 발견해낼 수 있게 될지도 모르며 그때는 블록체인이라는 시스템에 부정행위가 개입될 수 있다. 다만 이는 블록체인만의 문제는 아니고 SHA2를 사용하는 모든 금융기관, 정부기관에도 해당하는 문제이기에 필자는 아마 수년에서 수십년 안에는 모든 비트코인을 포함한 모든 해시함수가 SHA2에서 SHA3를 사용하게되지 않을까? 생각하게 된다.

비대칭 암호화 (공개키암호화)

비대칭 암호화 (혹은 공개키 암호화)는 어떤 특이한 보물상자를 상상하면 쉽다. 이 보물상자는 서로다른 두개의 열쇠가 있는데 열쇠 하나는 이 보물상자를 열수만 있으며 나머지 하나는 잠글수만 있다. 잠그는 열쇠로 보물상자를 열지는 못하며 여는열쇠로 보물상자를 잠그지는 못한다. 이 특이한 보물상자를 컴퓨터로 구현한 방법이 비대칭 암호화 방식이다. 여기서 두 열쇠는 공개키와 비밀키라는 이름으로 불리며 공개키와 비밀키중 어느쪽이 잠그는역할을 하고 어느쪽이 여는 역할을 하는지는 상황에 따라 달라지며 공개키는 모두가 그 내용을 확인할 수 있으며 비밀키는 자신만이 알고있다는 특징을 가진다.

개념적으로는 알겠지만 이것이 수학적으로 어떻게 가능한 것일까? 언젠가 임의의 두 소수 p와 q를 곱해서 생긴 값 p*q로부터 원래 p와 q값을 알아내긴 힘든 것을 원리로 암호화 하는 방식이 있다는 것을 들어본 적이 있는가? 이 방법이 바로 RSA라 불리는 대표적인 비대칭 암호화 방식중 하나이다. 다음과 같은 상황을 생각해보자. A라는 사람이 B라는 사람으로부터 숫자를 알아내고 싶은데 C라는 사람이 계속 엿듣고 있다. 그럼 어떻게 C는 모르지만 A는 B로부터 정보를 가져올 수 있을까?

일단 A는 서로다른 두 소수 p=11, q=37을 생각해둔다. 그리고 11*37=407 이라는 값과 p-1과 q-1와 서로소인 한 숫자 7을 B에게 알려준다. 그럼 B는 자신이 생각해둔 숫자 240의 e=7 제곱을 407로 나눈 값, 즉 240^7(mod 407) = 235를 A에게 알려준다. 그럼 A는 407의 오일러함수 값 360을 구해내고 7*103 – 360*2 = 1 이라는 사실을 이용해서 235^103(mod 407) = 240, B가 보내려고 한 숫자가 240임을 알 수 있다. 반면 407이 어떤 소수로부터 나온지 모르는 C는 오일러함수값을 구하는데 1부터 407까지의 숫자를 일일히 계산해보거나 407을 이루는 두 소수의 값을 찾아봐야하는데 이 과정은 시간이 꽤 소모된다. 만약 이를 11과 37이 아닌 A4종이에 적기도 힘든 긴 소수 2개를 사용하면 컴퓨터라도 복호화를 하는데 최소 수백년이 걸린다. 이것이 바로 RSA의 아주 기본적인 원리이다.

Note left of A: C가 볼수있는 내용들
A->B:p*q = 407
A->B: e = 7
Note over B: B encrypts 240 \nusing data \ngiven by A.
B->A: 235
Note over A: A decrypts 235 \nusing p and q.

복잡하다 느껴지는가? 괜찮다. 비트코인에서는 RSA를 안쓰고 ECC라는 더 복잡한걸 쓴다. (음...?) 그리고 둘다 제대로 이해하려면 기초적인 수학부터 전문적인 수학까지 그 자체를 마스터 하는데만 상당한 시간이 걸린다. 하지만 이 둘이 어떻게 작동되는지는 몰라도 이 둘의 특징만 파악하면 비트코인을 이해하는데는 문제가 없다. 그 특징이란 위 과정에서 p와 q라는 두 소수를 비밀키로 암호화된걸 복호화 했으며, p*q 와 e라는 두 수를 공개키로 암호화를 진행했고, 비밀키로부터 공개키를 만들어 낼 수 있고, 비밀키를 모르는 상태로 복호화를 하려면 엄청난 시간이 든다. 라는 것이다. 이는 비트코인에서 ECC의 원리를 이용한 ECDSA에도 비슷하게 나타난 특징이니 (단, 여기서는 비밀키가 암호화를 한다.) 참고해두자.

전자서명

처음 해시함수를 설명할때 해시값은 데이터가 변조되었는지 확인하는데 쓰인다고 언급했다. 만약 데이터 변조가 단순히 통신오류때문에 발생한것이라면 변조확인과정은 아주 쉽게 진행될 것이다. 하지만 만약 데이터가 악의적인 해커에의해 조작된 것이라면? 그 해커도 해시함수의 원리는 알고있을테니 당연히 우리에게 제공되는 데이터만 조작하지 않고 해시값도 조작해서 줄 것이다. 그럼 우리는 조작된 해시값과 데이터로 받은 데이터가 정상적인것이라고 속게 되어 해커는 성공적으로 조작된 데이터를 배포할 수 있을것이다. 이러한 상황을 어떻게 못하나? 라는 생각에서 나온것이 전자서명이다.

전자서명의 원리는 간단하다. 해시값을 비밀키로 암호화한 뒤, 공개키와 함께 암호화된 해시값을 배포한다. 암호화된 해시값을 받은 우리는 공개키를 이용해 복호화를 하고 파일의 해시값을 구해 복호화한 값과 구한 해시값을 비교해본다. 둘이 같은값이면 이 데이터는 조작되지 않았고 다르면 뭔가 문제가있다. 무척 간단한 방법이지만 이런 조치는 엄청 강력하게 작용한다.

note left of 송신자: 해커가 볼 수 있는 내용들
송신자->수신자: Data
송신자->수신자: Encrypted Hash
송신자->수신자: Public key

일단 해커가 데이터를 받는사람이 조작된줄 모르게 데이터를 조작하려면 어떻게 해야할까? 방법은 두가지이다. 조작된 데이터의 해시값과 원래 데이터의 해시값이 같게 조작을 하던가, 아니면 암호화된 해시값을 복호화했더니 조작된 데이터의 해시값이 나오게 하면 된다. 하지만 전자의 경우 위에서 밝혔다시피 우주의 나이정도의 기간도 매우 부족할정도로 오래걸리고 후자의 경우 비밀키를 모르면 조작된 데이터의 해시값의 암호화값을 구해낼 수 없다. 그러므로 이러한 단순한 조치만으로도 해커는 데이터를 남몰래 조작할 수 없다...... 라고하고 싶지만 눈치빠른사람은 눈치챘을 것이다. 그것은 바로 공개키도 같이 조작하면 수신자는 속을 수 밖에 없지 않은가? 라는 것이다.

맞다. 위 과정에서 공개키도 조작하면 수신자는 데이터가 제대로된건지 조작된건지 알길이 없다. 그래서 존재하는것이 신뢰기관이다. 신뢰기관이란 다른건 다 믿을 수 없어도 이거 하나만큼은 믿을 수 있어! 라는 느낌의 존재인데 여기서 제공된 공개키만큼은 아무런 개입이 없었다는걸 전재하에 모든 전자서명 시스템이 작동한다. 윈도우즈의 경우 출고때부터 마이크로소프트에서 제공하는 공개키가 내장되어 신뢰 가능한 소프트웨어를 구분하고, 웹사이트의 경우 인터넷 브라우저자체에 신뢰 가능한 몇몇가지 공개키가 저장되어 https 프로토콜을 구현하고 있다. 비트코인에서는 약간 기발한 방법으로 신뢰기관의 존재 없이 공개키가 믿을 수 있다는걸 보여주는데 이는 *트랜젝션*부분에서 자세히 다루겠다,