-
Hack it! if you can - 일상속 보안에 대해가볍게 읽는 시리즈 2020. 12. 6. 11:16
불변의 진리 - 아는 만큼 보인다
코로나로 인한 비대면화와 디지털 트랜스포메이션이 가속화되고 있는 지금, 컴퓨터 네트워크에 대한 의존성은 해가 갈수록 더욱 높아지고 있습니다. 디지털화가 되면 될수록 우리들은 중요한 정보들을 컴퓨터와 스마트폰을 통해 주고받을 텐데요. 이 정보들이 정말 안전한 걸까요? 평소에 관심 있게 찾아보신 분이 아니라면 대부분은 별다른 의심 없이 "내 정보들은 알아서 안전하게 관리되겠지"하고 무한 신뢰하기 십상입니다. 이런 얇은 믿음의 막 하나만을 믿고 우리들은 오늘도 중요한 정보들을 마구마구 외부로 쏟아내고 있습니다. 방금 전 보냈던 카카오톡이, 오늘 아침 Autoway 로그인할 때 사용했던 ID/PW가 어떻게 관리되고 있는지, 정말 안전한 건지 메커니즘을 이해한다면 조금 덜 불안하게 지낼 수 있지 않을까요?
이 글을 통해 "보안", 그중에서도 "암호화" 기법들에 대해 가볍게 다뤄볼 예정입니다! 암호화...! 듣기만 해도 500페이지는 넘어 보이는 어마 무시하게 두꺼운 책을 읽으면서 노트와 펜을 꺼내 경건한 마음으로 필기를 준비해야 할 것 같은 기분이 드신다면 절대 그러실 필요가 없습니다! 복잡한 건 하나도 안 나오고 비전공자도 쉽게 이해하실 수 있게 정말~정말~ 단순하고 가볍게 알아볼 거니까요! 그리고 생각보다 어렵지 않고 의외로 재미?까지 있습니다. 그럼 지금부터 우리 일상을 깊게 파고든 보안, 암호화에 대해서 한번 알아보겠습니다~!!!
해적들이 득실대는 공간, 컴퓨터 네트워크
컴퓨터 네트워크는 기본적으로 암호화되어 있지 않고 누구라도 중간에서 정보를 도청, 탈취, 변조할 수 있는 공간입니다. 이에 대해 비유를 들자면 무역품을 가득 실은 무역선이 해적왕이 되고픈 해적들의 대포와 총탄이 마구 난사되는 무시무시한 해협을 뚫고 가는 것 정도로 생각하시면 비슷합니다. 상당히 위험하게 들리죠?
그러므로 내가 보낸 패킷은 항상 해커들의 타깃이 될 수 있다는 다소 극단적인 가정이 필요합니다. 이렇게 무서운 곳을 뚫고 목적지까지 도착해야 하는 정보는 위협으로부터 안전하게 보호해야 하지 않을까요? 암호화하지 않고 정보(패킷)를 보낸다면 아래 같은 상황에 처하게 될 수도 있습니다.때문에 노출되어도 상관없는 정보가 아닌 이상은 정보를 송신하기 전에 암호화하는 과정은 필수적입니다!!
암호화란?
암호화라는 단어는 들어보셨을 텐데요. 암호화는 무엇일까요? 간단히 설명하자면 "해독할 수 있는 정보를 해독이 불가능하게 '암호키'를 통해 변환하는 것"입니다. 암호화되어 있지 않은 정보를 평문, 암호키를 통해 해독할 수 없는 상태로 바뀐 정보를 암호문이라고 합니다.
암호화를 위해서는 "암호키"가 필요한데 이 키가 암호화의 핵심입니다. 일반적으로 암호화와 복호화에 사용하는 키가 동일하기 때문에 이를 대칭키 암호화라고 합니다.
대칭키 암호화는 그 역사가 어마 무시하게 깁니다! 고대 로마에서부터 사용했던 "시저의 막대"라고 불리는 스키테일 부터 16세기 프랑스 외교관 비즈네르에 의해 고안된 "비즈네르 테이블", 그리고 영화화를 통해 어쩌면 가장 유명할 수도 있는 나치 독일의 암호 기계 "애니그마" 까지... 몇천 년에 걸친 정보를 꽁꽁 숨기려는 노력은 시간이 갈수록 정교하고 복잡하게 발전했지만 핵심 원리는 모두 동일했습니다. 정보를 암호화하는데도 "암호키"가 필요하고 암호화된 정보를 해독하는데도 동일한 "암호키"가 필요하다는 점입니다.
스키테일은 고대에 사용되었던 원시 암호 체계입니다. 스키테일에서 메세지는 긴 가죽에 알파벳을 나열해놓고 이를 막대에 둘둘 말아서 가로로 읽는 방식으로 메세지를 해독합니다. 스키테일에서 암호키는 무엇일까요? 가로로 메세지를 해독해야 하기 때문에 메세지를 보내는 쪽과 받는 쪽 모두 동일한 메세지를 보기 위해서는 막대의 두께가 같아야 할 겁니다. 때문에 "막대의 두께"가 암호키가 됩니다! 만약 막대의 두께가 노출된다면? 메세지는 곧바로 해독될 겁니다.
원문 : HYUNDAI
암호키 : 5각형 막대
암호문 : WAHGIEKYCKEJUEIGNNIEJWDPQOCAEWJOIUW
시간이 흘러 이런 원시적인 암호체계에서 조금 더 발전한 형태가 나타나기 시작합니다. 그중 대표적인 것이 비즈네르 테이블인데 프랑스 외교관이었던 블레즈 드 비즈네르가 고안한 것으로 알파벳을 다른 알파벳으로 치환하여 암호화합니다.
비즈네르 테이블이라고 부르는 이유는 이것이 실제로 26x26 형태의 테이블이기 때문입니다.
앗! 잠깐만요! 눈알이 핑핑 돌아가신다구요?! 무지막지하게 복잡할 거 같다구요? 워워~ 릴랙스~! 어렵지 않습니다.
아주 간단한 예시를 통해 동작원리를 알아보겠습니다! 비즈네르 테이블을 활용한 암호화를 위해서는 "원문(평문)"과 "키워드(암호키)"가 필요합니다.
원문(평문) : HYUNDAI
암호키(키워드) : CAR
라고 가정해보겠습니다.
우선 HYUNDAI 각각의 글자에 키워드를 하나씩 반복적으로 매핑 시켜줍니다. 평문의 길이가 짧은 경우는 키워드를 그냥 잘라줍니다.
HYUNDAI
CARCARC(AR)은 짧아서 짤림이렇게 되면 H와 C가, Y와 A가, U와 R이 이렇게 매핑됩니다.
H - C
Y - A
U - R
N - C
D - A
A - R
I - C
이제 위 테이블을 참조하여 H열에 C행에 적혀있는 알파벳으로 치환하고 모든 평문이 전부 치환될 때까지 이 과정을 반복합니다.
그럼 우리는 아래와 같은 암호문을 얻을 수 있습니다.
암호문 : JYLPDRK
비즈네르 테이블을 이용한 암호화는 이런 식으로 이루어집니다. 이렇게 암호화된 JYLPDRK를 정상적으로 해독하기 위해서는 반드시 "CAR"이라는 키워드(암호키)가 필요합니다.
어떠신가요? 원리가 생각보다 단순하죠?
시간이 또 흐르고 흘러 더욱 발전된 형태의 암호 체계가 만들어지기 시작합니다. 이제는 사람이 일일이 해야 했던 암호화와 복호화 과정을 기계를 통해 할 수 있게 되었습니다. 애니그마가 대표적인데요. 구조는 훨씬 정교하고 복잡해졌지만 핵심 원리는 비즈네르 테이블과 마찬가지로 사전에 정의된 규칙을 통해 문자와 문자를 치환하는 방식으로 암호화가 이루어집니다.
애니그마는 암호키로 회전자라고 불리는 26각형(A~Z) 톱니바퀴 여러 개와 회전자의 순열, 키보드 플러그 설정을 복합적으로 사용합니다. 이 암호 설정은 암호표(코드북) 책에 날짜별로 기재되어 되어 각 부대에 교부되었는데요. 이 코드북을 적에게 빼앗기기라도 한다면 모든 암호 통신이 무력화 되게 됩니다.
2차 세계대전 초기 독일군은 군의 효과적인 운용으로 전술적 우위를 점했으나 연합군은 애니그마 해독기를 통해 암호키를 해독하였고 결국 독일군은 암호키가 노출되는 바람에 전쟁 후반부 내내 연합군에게 전술적인 우위를 넘겨주고 말았습니다.
이렇듯 암호화의 모든 문제는 바로 이 "암호키"에서 시작됩니다. 보낸 정보를 받은 사람이 온전히 해독하기 위해서는 암호화하는 사람과 복호화 하는 사람이 모두 동일한 키를 공유해야 하는데 키를 공유하는 과정이 상당히 어렵기 때문이죠. 그렇다고 해서 키를 같이 전달할 수는 없습니다. 키를 같이 보냈다가 노출된다면 암호화는 말짱 도루묵이 되어버리니까요.
어떻게 해야 이 "암호키"를 나쁜 사람은 못 보고 우리 같이 착한 사람들만 볼 수 있게 할까요?
암호화의 딜레마
이것이 암호화의 딜레마입니다. 암호화와 복호화를 위해서는 "암호키"를 전달해야 하는데 이를 선택적으로 전달할 수 없다는 것이 가장 큰 문제입니다. 다른 말로 키 분배 문제(Key Distribution Problem) 라고 표현합니다.
지금까지는 암호키를 아군에게 어떻게 전달했을까요? 일반적으로는 적이 알 수 없는 밀실에서 아군들만 몰래 암호키를 공유하는 방식으로 공유했을 겁니다. 이런 방식은 구조적으로 몹시 취약할 수밖에 없는데 모든 사람들이 동일한 암호키를 공유하고 있으므로 단 한 명! 만이라도 암호키를 실수로 혹은 고의로 노출하게 된다면 모든 암호 통신이 무력화되어 버립니다. 암호 통신 참가자가 많으면 많을수록 취약점은 커지게 됩니다.
그런데 맙소사, 만약 어떤 배신자로 인해 암호키가 적에게 노출되었다는 사실을 알게 되었습니다. 이제 어떻게 해야 할까요? 노출된 암호키를 통해 통신한다면 사실상 평문으로 통신하는 것과 다르지 않습니다. 근본적인 해결책은 모든 통신 참가자들이 다시 밀실에 모여서 새로운 암호키를 공유해야 합니다. (맙소사)
하지만 모든 통신 참가자들이 다시 밀실에 참여할 수 있을까요? 운이 나쁘다면 그렇지 못한 경우도 생길 겁니다. 이런 경우는 결국 최대한 은밀하게 암호키를 직접 전달해야 합니다. 마치 고대 로마 전령이 스키테일 막대를 안주머니에 넣고 말 달리던 것처럼 말이죠. 이 상태는 암호화되어 있지 않은 "암호키"를 전달하는 것이기에 몹시 취약할 수밖에 없습니다. 최악의 경우에는 암호키가 중간에 적에게 탈취당할 수도 있습니다. 보안에서는 항상 최악을 가정해야 하기 때문에 이런 경우 내가 보낸 암호키는 반드시 적군에게 알려져 있다고 가정할 수밖에는 없습니다.
메세지를 전송할 때 키만 은밀하게 메세지에 실어서 보낼 수는 없을까요? 암호화된 키를 암호문에 추가해서 보내면 보낼 수는 있지만 문제는 암호화된 키를 해독하기 위해서 또 암호키가 필요하게되고 그렇다면 키를 위한 암호를 다시 전달해야 하는 모순에 빠지게 됩니다.
생각보다 해결이 쉽지 않습니다. 만약 우리가 이런 딜레마를 해결하지 못하고 암호 통신을 해야 한다면 아래 같은 상황에 처하게 될 겁니다.
우리가 카톡을 안전하게 사용하기 위해서는 회원가입을 하고 카톡을 보내기 전, 카톡 고객센터로 찾아가서 신원 인증을 마치고 암호키를 등록해야 합니다.
"앞으로 내가 카톡 서버에 메세지를 보낼 때 암호키 %#@%!@#로 암호화해서 보낼 건데 혹시나 받으면 당황하지 말고 %#@%!@# 암호키로 해독해 주세요. 그러면 내가 누구한테 어떤 메세지를 보내고 싶은 건지 확인할 수 있는데 다시 메세지를 %#@%!@# 암호키로 암호화해서 보내려는 사람한테 보내주세요. 만약 암호키가 외부에 노출이라도 된다면....알죠..? ^_^ (찡긋)"
이게 끝이 아닙니다. 카톡으로 통신하고 싶은 부모님, 친구들을 저녁 늦게 불러다 모아서
"여러분들! 지금부터 제가 보낸 카톡은 %#@%!@#로 암호화된 상태에서 전송될 예정입니다. 그러니까 메세지를 받으면 당황하지 말고 %#@%!@#로 해독한 다음 메세지를 보시면 됩니다, 그리고 암호키가 노출되지 않게 주의해 주세요!"
이렇게 복잡한 과정을 거쳐야만 안전한 통신을 할 수 있습니다. 만에 하나 새로운 카톡 친구를 추가하고 싶다면 카톡을 하기 전에 친구에게 암호키를 꼭 공유해 줘야 합니다.
어휴~~ 복잡해도 너무 복잡하군요. 뭔가 좋은 방법이 없을까요?
비대칭키 암호화
위에서 보시다시피 대칭키 암호화는 암호화에 사용되는 "암호키"를 통신 참가자들에게 분배하는 문제가 몹시 까다롭습니다. 하지만 비대칭키 암호화는 이런 키 분배 문제를 해결하는데 아주 탁월한 구조를 가지고 있습니다. 이것이 가능한 이유는 온전한 암호키가 아닌 부분적인 암호키를 통해 암호화하는 비대칭키의 특수성 때문입니다.
비대칭키는 온전한 하나의 암호키가 아니라 2개의 키로 분리되어 있습니다. 혹시 공개키 혹은 개인키라는 용어를 들어보신 적이 있으신가요? 비대칭키 각각의 키를 공개키(Public Key), 개인키(Private Key)라고 합니다.
공개키와 개인키는 항상 쌍으로 존재하는데 공개키 혼자 혹은 개인키 단독으로는 의미가 없습니다.
좀 더 쉬운 이해를 돕기 위해 비유를 든다면 공개키는 "자물쇠"이고 개인키는 "열쇠"에 해당됩니다. 때문에 비대칭키를 만든다는 말은 자물쇠와 자물쇠 전용 열쇠 쌍을 하나 만드는 것이라고 생각하시면 됩니다. 자물쇠 홀로 혹은 열쇠 홀로 있다면 전혀 쓸모가 없습니다.
공개키가 자물쇠, 개인키가 열쇠인 건 알겠습니다. 그런데 비대칭키는 키 분배 문제를 어떤 방식으로 해결할까요?
비대칭키를 통한 암호화 메커니즘은 아래와 같이 이루어집니다.
1. 통신을 위해서 송신자는 자물쇠와 열쇠를 하나씩 생성합니다. (공개키와 개인키 한 쌍을 생성합니다.)
2. 송신자는 자물쇠를 수신자에게 보냅니다. (공개키를 수신자에게 전달합니다.)
(이 과정에서 해커도 자물쇠(공개키)를 얻을 수 있습니다.)
3. 수신자는 자물쇠를 받아서 메세지에 자물쇠를 채웁니다. (공개키를 수신하여 정보를 암호화합니다.)
4. 수신자는 자물쇠 채워진 정보를 다시 송신자에게 보냅니다. (공개키로 암호화된 정보를 다시 송신자에게 전달합니다.)
5. 송신자는 열쇠를 통해 정보에 채워진 자물쇠를 걷어내 원본 데이터를 얻을 수 있습니다.
(송신자는 개인키로 공개키를 해독합니다.)
(이 과정에서 해커는 자물쇠 채워진 정보(공개키로 암호화된 정보)를 얻을 수 있지만 열쇠(개인키)가 없기 때문에 해독할 수 없습니다.)
이런 방식을 통해 이루어집니다. 중간에 존재하는 해커는 송신자와 수신자 간에 주고받는 데이터를 모두 캡처할 수 있지만 개인키(열쇠)가 없기 때문에 암호화된 정보를 해독하지 못하기 때문에 데이터 전달에 있어서 안전하게 됩니다.
정말 신기하지 않으신가요? 어떻게 이런 마법 같은 일이 가능한지 원리를 알고 싶은 분은 링크를 참조해 주세요~! (디피헬만 키 교환 알고리즘)
일반적으로 비대칭키는 "대칭형 암호키"를 공유하는 데 사용합니다. 여러모로 좋아 보이는 비대칭키를 데이터 암호화에 직접 쓰지 않고 암호키를 교환하는 데만 쓰는 이유가 있습니다. 비대칭키를 통한 암호화는 너무 비효율적이기 때문입니다.
대칭키와 비대칭키는 각각 구조적 취약성, 효율의 문제가 있지만 서로의 단점을 보완해 줄 수 있기 때문에 둘을 혼용함으로써 훌륭한 암호 체계를 구축할 수 있습니다!
우리가 사용하는 거의 모든 암호 통신 체계는 이렇게 비대칭키와 대칭키를 혼용한 형태입니다. 우리가 웹브라우저를 통해 웹서핑 할 때, 카카오톡으로 메세지를 보낼 때, 공인인증서를 통해 인증할 때 모두 활용되고 있습니다!
이 둘의 조합은 거의 완벽해 보입니다. 비대칭키를 통해서 암호키를 공유하고 공유된 암호키를 통해서 효율적으로 암호통신을 하니까 말이죠! 흠잡을 데 없어 보이지만 암호화에는 치명적이고 근본적인 문제가 있습니다.
암호화의 위험성
바로 암호화 자체의 "위험성"입니다. 지금까지 암호화의 목적은 정보를 안전하게 전달한 후에 해독하여 원본 데이터를 복원하기 위한 것이었습니다. 아무리 복잡하고 난해한 암호 알고리즘이 적용되었다고 하더라도 "백만 분의 일의 확률"로 암호키가 노출된다면 암호화했던 정보들은 모두 복원됩니다. 하지만 정보의 속성상 변경이 힘든 경우가 존재하고 모종의 이유로 암호 체계가 붕괴되었다고 가정했을 때 한 번만 노출되어도 치명적인 경우가 있습니다.
이런 정보에는 어떤 것이 있을까요?
가장 떠올리기 쉬운 정보로는 생체 정보들이 있을 겁니다. 지문이나 홍채 패턴, 얼굴형, 목소리 음역대, DNA 염기서열 같은 타고난 정보들은 임의로 변경이 거의 불가능합니다. 때문에 원본 정보가 노출된다면 해커는 이 생체 정보를 복원하여 활용할 수 있고 생체 정보를 활용한 인증 체계는 쉽게 무력화 시킬 수 있게 됩니다. 때문에 이런 정보들을 암호화하여 저장하는 것은 매우 위험합니다. 그럼 어떻게 해야 할까요?
복원 불가능한 암호화, 해시(Hash)
구조적으로 암호화는 설계 의도가 원본 데이터의 복원을 염두에 둔 것이기에 문제가 발생할 수밖에 없습니다.
위에서 살펴본 암호화의 과정이 "원문"을 "암호문"으로 바꾸는 과정이고 복호화의 과정은 반대로 "암호문"을 "원문"으로 바꾸는 과정이었습니다. 암호화 과정을 "함수"로 표현할 수 있다면 복호화 과정은 "역함수"로 표현 가능합니다.
해커가 암호문을 복호화 하여 원래 정보를 얻을 수 있다면 끝입니다! 끝! 그래서는 안되겠죠?!
만약 암호화된 데이터가 해커에게 노출된다고 하더라도 역함수가 없다면, 즉 복원할 수 있는 방법이 없다면 원본 데이터를 안전하게 지킬 수 있지 않을까요?
이를 위해 데이터를 복원할 수 없도록 망치로 때리고 톱으로 썰고 믹서기로 드르륵 갈아서 아침에 마시는 생식 주스마냥 원래 형태조차 알 수 없게 묵사발 내는 데는 도가 튼 친구가 컴퓨터에도 있습니다! 바로 해시함수입니다!!
해시함수는 데이터를 비트 단위로 분해한 후에 일부만 재조립 해버려서 처음 들어간 원본 데이터는 형체를 알아볼 수 없게 파괴해버립니다! 즉, 원본 데이터가 소실되어 버립니다! 그리고 깔끔하게 정해진 길이의 출력을 내놓는데 이 출력을 "해시값"이라고 합니다.
또한 해시함수는 해체-분해 작업에 대해서는 프로페셔널 의식 충만한 절도 있는 친구라 완벽하게 정해진 절차에 의해서 항상 한 치의 오차도 없이 똑같은 결과물을 만들어냅니다.
함수에 들어가는 입력이 동일하다면 항상 같은 출력을 내는 속성(멱등성) 덕분에 해시함수를 다용도로 유용하게 사용할 수 있게 해줍니다. 만약 입력 데이터가 같은데도 매번 다른 해시값이 나온다면 해시함수는 바로 실업자가 되어버렸을 겁니다.
해시함수는 극도로 예민한 친구이기 때문에 입력에 아주 민감하게 반응합니다.
해시함수에 오렌지 먼저 넣고 라임 넣어서 갈았을 때는 맛있고 상큼한 오렌지라임 쥬스가 나오지만 반대로 라임 먼저 넣고 오렌지 넣어서 갈았을 때는 녹진하고 텁텁한 녹조라떼가 나올 수 있다는 말입니다. 좀 너무하네요~ 라임이나 오렌지가 둘 다 들어가는 건 똑같은데 순서좀 바뀌었다고 결과값이 이렇게 달라질 수 있다니요~~
그래도 어쩔 수 없습니다. 해시함수는 엄격 근엄 진지한 친구니까요..
이렇게 든든한 해시함수의 특징을 정리해보자면
1. 동일한 입력에 대해 항상 같은 해시값을 반환한다.
2. 입력 데이터의 크기가 얼마나 크고 작던 항상 정해진 길이의 해시값만 반환.
3. 입력에 매우 민감해서 아주 약간만 변해도 해시값을 전혀 예측할 수 없게 바뀜
해시함수도 하나가 아니고 형제들이 많이 있는데요 유명한 해시함수들을 간단히 소개해보자면 MD5, SHA-1, SHA-256 등이 있습니다.
우리가 Autoway를 로그인 할때 벌어지는 일
그럼 해시함수가 암호화에 어떻게 사용될까요?
우리들은 계정에 접속하기 위해 ID와 패스워드를 통해 로그인합니다.
여기서 ID는 사용자 식별을 위한 정보이고 비밀번호는 사용자가 맞는지 인증하기 위한 정보입니다. 이 정보들은 네트워크를 통해 서버로 전달되는데요. 내가 보낸 정보가 실제 내가 맞는지 확인이 필요하기 때문에 서버는 ID와 패스워드를 서버 데이터베이스에 저장해놓아야 합니다. 우리가 보낸 패스워드를 대조하여 "정답"인지 "오답"인지 확인을 해야 하니까요. 하지만 이 정보가 일반적인 암호화를 통해 "복원이 가능한 상태"로 저장되어 있다면 아주 희박한 확률로 서버의 데이터베이스가 해킹되고 암호키가 노출되었을 때는 ID와 패스워드가 동일한 모든 계정들의 ID와 패스워드를 변경해야 하는 상황에 놓입니다. 사람들은 편의를 위해 일반적으로 동일한 ID와 패스워드를 반복적으로 사용하는 경향이 강하기 때문에 노출되었을 때 큰 보안 위협이 됩니다.
이런 경우에 해시함수를 도입할 수 있습니다. 해시함수는 원본 데이터가 소실되기 때문에 소실된 정보인 "해시값"을 저장하고 있고 만에 하나 이 값이 노출된다고 하더라도 해시값으로는 원래 패스워드를 알아낼 수가 없기 때문에 "이론적"으로는 원래 비밀번호가 뭔지 알 수 없습니다.
진짜 비밀번호가 맞는지 서버가 어떻게 확인할 수 있지?하는 물음이 생기실 수도 있는데 서버 입장에서는 원본 패스워드가 뭔지는 모르겠지만 사용자가 입력한 패스워드가 동일한 해시함수를 거쳐 나온 해시값이 동일하므로 아마 패스워드일 것이라고 가정하여 인증을 허용해 줍니다.
또한 우리는 로그인할 때마다 싱싱한 비밀번호(원문)를 그라인더에 공급해 주기 때문에 데이터 소실에 대한 걱정을 할 필요가 없습니다!
해시함수를 활용한 인증 체계는 이렇게 동작합니다. 그런데 말입니다. 내가 사용한 비밀번호와 해시값은 엄연히 다른 값인데 누군가 내 비밀번호랑 동일한 해시값을 만드는 비밀번호를 찾으면 보안이 무력화되지 않을까요?
해시함수의 취약점
해시함수는 복호화가 불가하지만 완전무결한 건 아닙니다. 위 설명에서 해시함수는 고정된 길이의 해시값을 생성한다고 했습니다. 입력으로 들어갈 수 있는 정보의 경우의 수는 무한대인데 출력은 무한대가 아닌 유한한 값이기 때문에 언젠가는 다른 입력에 대해서 같은 해시값이 생길 수밖에 없습니다!
이런 현상을 "해시 충돌"이라고 하며 해시의 취약점 중 하나입니다. 때문에 해시함수를 활용한 인증 체계는 확률적으로 취약점이 있습니다. 더 상세한 내용이 궁금하시면 아래 링크 참고 부탁드립니다~!
충돌이 생길 수밖에 없다면 이를 어떻게 극복할 수 있을까요? 우선 충돌할 확률에 대해 확인해봐야겠군요? 해시값의 길이는 고정길이라고 하는데 일반적으로 많이 사용되는 SHA-1의 해시값은 160bit이고 SHA-256은 256bit 입니다. 만약 비밀번호를 SHA-256 해시함수를 통해 암호화했다고 가정한다면 2의 256제곱 분의 1 확률로 비밀번호가 겹치게 됩니다. 2의 256제곱이라... 얼마나 큰 숫자인지 감이 오시나요? 2의 256제곱은 지구에 존재하는 모래 알갱이 개수보다 수천억 배 이상 큰 숫자입니다. 즉, SHA-256으로 암호화된 비밀번호가 겹칠 확률은 우주에 존재하는 수천억 개의 행성 중에 하나를 골랐는데 그게 하필 지구고 해운대 바닷가에 가서 작디작은 모래 알갱이 한 개를 집었는데 그 알갱이가 작년에 내가 집었던 모래 알갱이와 똑같을 확률입니다.
충돌할 확률은 거의 0에 수렴한다고 봐도 무방합니다. 때문에 안전하다고 볼 수 있습니다. 256bit가 이 정도인데 384bit나 512bit는 거의 무한대에 가까운 크기라고 봐도 과장이 아닙니다. 이렇듯 해시함수를 통한 암호화는 해시값의 크기가 곧 안전성이라고 할 수 있습니다.
비밀번호만으론 완벽하지 않다
이제 우리의 비밀번호가 어떻게 관리되고 있는지 이해했습니다. 비밀번호 해킹이 구조상 매우 힘들다는 것도 이해하셨을 겁니다. 하지만 그럼에도 불구하고 우리는 종종 해킹을 당합니다. 혹시 해킹을 당해본 경험이 있으신가요??
저는 초등학생 때 좋아하던 게임 계정을 해킹당한 추억이 있는데 지금도 종종 그때를 생각합니다.
몇 달간 힘들게 모아왔던 골드와 소중한 아이템들이 모두 사라져 발가벗고 있는 캐릭터의 모습을 봤을 때 그 좌절과 상실감은 정말,,,,8ㅅ8,,,,
당시에는 지금과 달리 보안에 대한 개념이 약해서 비밀번호도 영대소문자 특수문자를 섞어서 써야 하는 그런 규칙 없이 6글자만 넘으면 비밀번호로 사용을 허용해 주는 관대한 시절이었기 때문에 숫자 6개를 비밀번호를 사용하는 만행?을 저질렀습니다. (그러니까 해킹을 당하지...!)
하지만 비밀번호에 대한 수준이 많이 강화된 지금도 해킹 사례는 심심치 않게 찾아볼 수 있습니다. 이게 가능한 이유는 비밀번호를 복잡하게 만들고 안전하게 관리한다고 하더라도 결국 우리가 비밀번호를 자주 사용하기 때문에 외부로의 노출 빈도가 높을 수밖에 없고 이 과정에서 생기는 반복적인 노출로 인해 비밀번호를 유추할 수 있는 상황이 만들어지기 때문입니다. 그렇기 때문에 비밀번호를 일정 주기로 변경해야 한다는 정책 또한 생기게 된 것입니다.
때문에 비밀번호 하나만으론 안전하다고 하기 힘듭니다. 인증이 전쟁이라면 비밀번호라는 방어선 단 하나만을 믿고 있는 것이죠. 방어선이 한 번이라도 뚫린다면 즉시 패배하게 됩니다.
그래서 많은 인증 체계에서는 비밀번호 외에 2차 인증 체계를 추가로 도입합니다. 2차 인증을 함으로써 얻을 수 있는 이익은 명료합니다. 단순하게 인증 절차가 많아질수록 보안은 향상됩니다.
2차 인증의 종류
그럼 2차 인증에 사용되는 인증 체계에는 뭐가 있을까요? 2차 인증으로 자주 사용되는 건 2차 비밀번호 혹은 OTP가 있습니다. 2차 비밀번호는 로그인 할 때 사용했던 비밀번호와 똑같습니다. 비밀번호를 2중으로 설정함으로써 안전성을 높이는 것이지만 비밀번호를 하나 더 기억해야 한다는 번거로움이 있습니다. 또한 2차 비밀번호도 결국 비밀번호와 같은 문제점을 가지고 있기 때문에 주기적으로 변경해 줘야 하고 반복적으로 노출했을 때 해킹 당할 위험성 또한 고스란히 가지고 있습니다.
그래서 우리는 2차 비밀번호보다는 OTP를 주로 사용하는데 OTP가 어떻게 동작하는지 궁금하지 않으신가요? 그리고 정말 안전한지도요~! 그래서 우리들이 많이 사용하는 OTP에 대해 개념과 원리를 간단히 설명해보려 합니다.
OTP를 통한 2차 인증
인증 체계에서 인증키로 사용 가능한 키들을 모아놓은 집합을 키 공간(Key Space)이라고 합니다.
가장 쉽게 이해할 수 있는 대표적인 키 공간의 사례로는 보안카드가 있습니다.
보안카드에는 수십 개의 인증 키가 될 수 있는 키들이 모여있습니다. 보안카드 인증 과정에서는 키 공간(코드표)에 있는 몇 개의 키들을 무작위로 물어보는 방식으로 인증을 진행합니다. 과거에는 보안카드 또한 2차 인증에 자주 사용되었지만 현재는 그 사용빈도가 현저히 줄어들고 있는데 그 배경에는 보안카드가 가지고 있는 취약점이 있습니다.
보안카드의 취약점은 키 공간이 변경되지 않는다는 점입니다. 한 번이라도 보안카드를 사용해 보신 분이라면 보안카드에 "사진으로 찍어서 보관하지 말라"는 경고 문구를 보신 적이 있으실 겁니다. 그 이유는 보안카드는 키 공간이 바뀌지 않기 때문에 반복적으로 노출되면 해킹 시도에 무력해지기 때문입니다. 우리가 비밀번호를 어딘가에 적어두고 사용하면 안 되는 이유와 완벽하게 똑같습니다. 즉, 형태만 약간 다를 뿐 결국 보안카드도 비밀번호와 똑같은 취약점을 가지고 있기 때문에 사용이 권장되지 않는 것입니다.
비밀번호나 보안카드의 취약점은 키 공간이 항상 정적으로, 바뀌지 않는다는 것이었습니다. 그럼 키 공간을 동적으로 설정할 수 있는 방법이 없을까요?
이 취약점을 해결하기 위해 고안된 것이 바로 OTP(One-Time-Password)입니다. OTP는 번역하자면 "일회용 비밀번호"라는 의미인데 이름에서도 유추할 수 있듯이 OTP는 일회용으로 키 공간을 생성하여 인증하기 위한 목적으로 고안되었습니다.
위 OTP는 실제 로그인할 때 사용되는 OTP 키입니다. 비밀번호와 함께 저 OTP 키를 사용한다면 정말로 로그인할 수 있을 겁니다. 그런데 OTP 키를 이렇게 이미지로 올려도 보안에 문제가 없을까요?
문제가 있을 수 있습니다. OTP 키가 생성되고 1분 동안은요. 하지만 1분이 지난 뒤에는 저 OTP 키는 아무런 쓸모도 없습니다. 그래서 이렇게 당당하게 올릴 수 있는 것이지요. (1분이 훌쩍 지났기 때문에 이제 위의 OTP 키로는 정상적으로 인증할 수 없습니다)
OTP 키는 이렇게 제한된 시간 안에만 유효한 수명이 1분짜리 일회용 비밀번호입니다! OTP의 원리는 뭘까요?
OTP의 원리
OTP 인증 절차에는 2명이 존재하는데 하나는 인증하고 싶어 하는 "인증자"와 인증을 허용해 줄 것인지 판단하는 "인증서버"가 있습니다. 인증자는 정해진 규칙에 의해 OTP 키를 생성하여 OTP 키를 인증서버로 전송합니다. 그럼 인증서버는 인증자가 생성한 OTP 키가 자신이 생성한 OTP 키와 동일한지 확인 후 인증을 허용해 주는 형태입니다.
그럼 인증자는 어떻게 OTP 키를 만들어내는 걸까요?
OTP 키 생성에서 가장 중요한 요소가 있습니다. 바로 시간입니다. 시공간이 분리되지 않는 이상 우리들은 모두 같은 시간을 살고 있으며 모든 컴퓨터들도 같은 시간을 공유합니다. OTP는 시간을 기준으로 키를 만들어 냅니다.
"엇~ 그런데 시간은 지역별로 다르지 않나요? 한국이랑 미국은 시간이 다를 거 같은데요?" 맞습니다. 때문에 사전에 인증자와 인증서버 간에 시간이 동기화되어야 합니다. 물론 기기마다 최대 몇 초의 오차가 발생할 수 있지만 허용 시간 범위를 충분히 길게 설정한다면 이런 불일치는 큰 문제가 되지 않습니다. 그리고 이 시간 범위는 일반적으로 1분 정도입니다.
그런데 문제가 하나 있습니다. 만약 시간만으로 키를 만들어낸다면 모든 인증자와 인증서버는 항상 동일한 OTP 키만을 생성할 것입니다. 시간은 누구에게나 동일하기 때문에 누가 인증하더라도 OTP 키가 같을 것이므로 보안에 도움이 되지 않습니다. 때문에 시간 외에도 추가적으로 인증자와 인증서버 간에 동일한 값을 하나 공유하는데 이 값을 시드라고 부릅니다. 바로 이 시드가 OTP 보안의 핵심입니다. 인증서버에게 시드값은 사용자를 식별할 수 있는 값이 됩니다.
사전에 인증자와 인증서버는 "시간"과 "시드"를 공유했기 때문에 각각 독립적으로 OTP 키를 계산할 수 있고 덕분에 인증자와 인증서버 간에는 통신 없이도 항상 같은 OTP 키를 생성하는 것이 가능해집니다.
그런데 OTP 키도 해킹할 수 있지 않을까요? 겨우 6~8자리 숫자밖에 안되어서 해킹이 아주 쉬워 보이는데요. 당연하게도 OTP 키 또한 해킹이 가능합니다. 하지만 생각보다 어려운데 왜냐하면 생성된 OTP 키는 1분이라는 아주 짧은 시간만 유효하기 때문입니다. 1분간 모든 컴퓨터 자원을 총동원해서 풀려고 노력해도 그 안에 풀지 못한다면 그간 들인 노력이 모두 물거품이 되어버립니다. 비유하자면 수학 한 문제를 풀라고 줬는데 그렇게 어려운 문제는 아니라 시간을 충분히 주면 풀 수 있지만 1분 안에 풀지 못하면 그 문제는 폐기되고 갑자기 새로운 문제로 바뀌는 것이죠.
이런 특징으로 인해 OTP 키를 활용한 보안이 가능한 것입니다.
하지만 OTP 또한 취약점이 존재합니다. 시드를 통해 유니크한 OTP 키를 만들어 내는 구조이므로 시드가 노출된다면 OTP 또한 다른 인증 체계와 마찬가지로 쉽게 붕괴됩니다. 때문에 시드값이 외부로 노출되지 않게 조심해야 합니다.
하지만 OTP는 다른 체계에 비해 장점이 있는데 일반적인 상황에서 시드는 노출되지 않는다는 점입니다. 시드는 숨겨져 있기 때문에, 시드가 노출되는 시점은 제일 처음 동기화를 맞추기 위해 시드를 설정하는 시점에만 노출이 있고 그 외에는 계속 숨겨져 있습니다. 물론 시드를 통해 생성되는 OTP 키가 무력화될 수도 있지만 이건 위에서 설명했다시피 겨우 1~2분이라는, 아주 빠른 컴퓨터 입장에서도 결코 쉽지 않은 시간제한이 있기 때문에 일반적으로는 해킹이 어렵습니다.
이렇게 OTP는 비밀번호를 기억하지 않아도 된다는 장점과 시드만 노출되지 않는다면 상대적으로 안전하다는 장점으로 인해 현재 2차 인증 수단으로 널리 사용되고 있는 것입니다.
읽어도 읽어도 끝나지 않는 글에 많이 지치셨을 거 같습니다. 글이 너무 길어서 죄송합니다. ㅜㅅㅜ 이제 곧 끝납니다.
이 글을 통해 암호화와 복호화의 개념에 대해 이해하고 컴퓨터 네트워크를 통해 데이터를 주고받을 때 어떻게 암호키를 교환하고 암호화하는지에 대해 알아봤습니다. 회원가입을 할 때 혹여나 내 비밀번호가 노출되지는 않을까 하는 걱정을 이제 한시름 덜게 되기도 했구요. 일상에서 자주 사용되는 OTP를 사용하는 이유와 그 원리에 대해서도 간략히 이해할 수 있게 되었습니다.
이 정도의 내용만 이해하고 계셔도 우리가 사용하고 있는 암호체계의 대부분 이해하신 것이라고 확신합니다.
비전공자도 쉽고 재미있게 읽을 수 있는 글을 작성하려고 노력했는데 암호체계의 설계 의도와 이론적인 배경을 설명하려다 보니 다소 복잡해진거 같습니다. (분량이 곱배기가 된 건 덤이구요..하하..) 가볍게로 시작했지만 TMI로 끝난 거 같아 많이 아쉽습니다만 앞으로 스마트폰과 컴퓨터를 사용하시면서 "아~ 이게 이런 원리로 동작하는 거구나~" 하며 기억해 주신다면 감사하겠습니다... ^_^ b
그럼 이만 글을 마치겠습니다.
분량 조절에 대실패해 진격의 TMI가 되어버렸지만 그래도 즐겁고 유익한 컬럼이 되었기를 바랍니다! 꺄르륵!
무지 긴 글 읽어주셔서 정말 정말 감사합니다! ㅎㅅㅎ b
'가볍게 읽는 시리즈' 카테고리의 다른 글
문자열 인코딩 완벽 정복하기(for 개발자) (14) 2020.12.05 가상화폐에 대한 내 생각 (0) 2017.06.28 통신료가 사라진 세상 (0) 2017.06.22