'Hash 해시' 는 크게 컴퓨터 공학에서 말하는 큰 개념으로서 Hash 와
암호학에서의 의미(단방향 암호화의 한 종류인 Hash ),
그리고 자료구조로써 활용되는 Hash 로 나누어 볼 수 있습니다.
결국 모두 같은 Hash 이므로 각 분야가 집중하는 기능/속성에 따라 활용법의 차이가 있는 것일 뿐입니다.
이번 시간에는 '암호학에서의 Hash' 에 대해서 알아보겠습니다.
컴퓨터 공학에서 말하는 큰 개념으로서 ' Hash ' 가 궁금하다면 아래글을 먼저 봐주세요.
자료구조로써 활용되는 ' Hash ' 가 궁금하다면 아래글을 봐주세요.
결론부터 말하자면 암호학에서 'Hash' 는 단방향 암호화의 한 종류로 활용됩니다.
닥스훈트(개의 한 종류)를 이해하기 위해서는 먼저 개에 대한 이해가 되어있어야 할 것입니다.
그렇기 때문에 간단하게라도 암호화의 기본 개념에 대해 먼저 알아보도록 하겠습니다.
'암호화 Encryption' 는 말 그대로 '평범한 정보' 를, 그 의미를 읽어낼 수 없게 '암호 정보' 로 변환하는 것을 말합니다.
반대로 암호문을 해독하여 평문으로 다시 바꾸는 것, 다시 정보의 의미를 알아볼 수 있게 하는 것을 '복호화 Decryption' 라고 합니다.
그리고 이 암호화 와 복호화를 수행하는 특정 방법을 '암호화 알고리즘(암호화 함수)' 이라고 합니다.
그리고 이러한 암호화는 복호화가 가능한 '양방향 암호화 two-way encryption'와
복호화가 불가능한 '단방향 암호화 one-way encryption'로 나눌 수 있습니다.
오늘 저희가 알아볼 'Hash' 가 바로 이 복호화가 불가능한 단방향 암호화의 한 종류인 것 입니다.
그럼, 암호화를 통해 정보를 외부의 위험으로부터 지킨다는 건 알겠는데,
복호화가 불가능해 다시 알아볼 수도 없는 Hash 암호화는 도데체 왜 필요한 걸까요?
Hash함수는 어떠한 입력값에 대해서 동일한 출력값을 보장한다는 '고유성'의 속성이 있습니다.
이를 활용하면 '비밀번호' 같이, 유출되었을 때 굉장히 위험한 데이터를 보관하고 있기가 쉬워지는데요.
바로 User 가 회원가입을 할 때 입력한 비밀번호를 Hashing 하여 Hash 값으로 보관하는 것이죠.
Hash 는 고유의 출력값을 가지니, 비밀번호를 알진 못해도
Hash 값이 일치 하는지를 확인하는 것으로 User 검증이 가능해 지는 것입니다.
그리고 Hash 는 복호화가 불가능한 단방향 암호화이기 때문에
보관하던 Hash 값이 유출된다고 해서 비밀번호가 노출될 위험도 없는 것 입니다.
우리가 비밀번호를 잊어버리면 새로운 비밀번호를 입력하라고 할 뿐 찾을 수 없는 이유도 바로 여기 있습니다.
데이터 베이스도 저희의 비밀번호의 Hash 값을 저장하고 있을 뿐 저희의 비밀번호를 알진 못하는 것이죠.
그리고 Hash 는 입력값이 아주 조금만 변해도 결과값은 아주 크게 달라지는 특성이 있는데요.
일명 '눈사태 효과' 라고 불리는 이 특성 덕분에 변경 감지 코드 MDC(Modification Detection Code) 로 활용되기도 합니다.
어떠한 파일이 원본의 상태와 완전히 동일한지 확인하기 위해,
원본 파일의 Hash값을 가지고 있다가 이후 비교할 파일의 Hash값과 일치하는지를 확인하는 것이죠.
이러한 확인 과정을 어떠한 조작이나 훼손 등의 결함이 없다는 의미에서 '무결성을 검증한다'라고 말합니다.
이렇게 'Hash' 를 활용해 무결성 검증을 하면 아주 미세한 변경도 쉽고 빠르게 잡아낼 수 있는 것입니다.
우리가 많이 들어봤던 비트코인의 '블록체인' 도 거래 내역의 무결성을 검증하기 위해 바로 이 Hash 개념을 사용한답니다.
그렇다면 이런 Hash 암호화는 어떤 한계점을 가지고 있을까요?
Rainbow Table (레인보우 테이블)
'Rainbow Table' 은 사람들이 자주 사용하는 암호 유형이나 복잡하지 않은 암호문들을
미리 여러 Hash 함수로 돌려보고 그 Hash값들을 모두 모아둔 표입니다.
그러니 복잡하지 않은 비밀번호를 사용한다면, 이미 공격자들이 Hash함수에 대입해보고
레인보우 테이블에 올려둔 데이터를 비밀번호로 사용하고 있는 것일 수도 있습니다.
그래서 이러한 위험으로부터 data 를 지키기 위해 'Salt(솔트)' 라는 기법이 존재합니다.
Salt 는 이름 그대로 Hashing 의 과정 전에 '임의의 문자열을 덧붙이는 방식'으로 소금을 치는 것입니다.
그럼 아무리 간단하고 자주 사용하는 유형의 쉬운 암호문이라고 해도 임의의 문자열을 알아내지 못하는 이상
레인보우 테이블이 무의미해지게 되는 것이죠.
무차별 대입 공격 (Brute force attack)
사실 'Hash 함수' 는 짧은 시간안에 원하는 data 를 검색하기 위한 자료구조로써 처음 설계되었습니다.
그렇기 때문에 태어나길 빠른 처리속도를 가지고서 태어난 셈이죠.
문제는 해커들이 공격을 하려고 할 때도 이러한 특성이 도움을 준다는 것입니다.
'무차별 대입 공격'은 그 이름에서도 알 수 있 듯 Hash 값을 생성해
해킹할 대상의 Hash 값과 맞을 때까지 비교해보는 공격인데요.
만약 해커들에게 무한정의 자원과 시간이 주어진다면 Hash 함수가 뚫리는 것은 필연적 입니다.
무차별 대입 공격에 있어서 Hash의 한계점은 말 그대로 '시간 문제'인 것입니다.
그래서 등장한 기법이 'Key Stretching (키 스트레칭)' 입니다.
Key Stretching 은 한번 Hashing 을 통해 얻은 Hash 값을 다시 Hash함수로 돌리는 방법 입니다.
스트레칭을 하듯 Hashing 과정을 쭉 쭉 늘려준다고 생각하면 이해가 쉽습니다.
Hashing 을 돌리는 횟수 또한 data 를 관리하는 입장에서 공개하지 않을 수도 있는 것이구요.
만약 공개된다 하더라도 자신의 임무(무차별 대입 공격을 방해하는 것)을 해내는 데에는 별 지장이 없습니다.
예를 한번 들어 보겠습니다. 이러한 Key stretching 기법을 썼더니
User 들의 비밀번호 검증에 0.2 초 정도의 시간이 더 소요되었다고 생각해 봅시다.
각 User 개개인이 로그인을 하는데 걸리는 시간으로는 아무 문제가 없을 수 있습니다.
하지만 1초에도 몇백억 단위의 값을 대입해보며 무차별 대입 공격을 하는 해커들에게는
매 대입마다 0.2의 시간이 더 소요된다면, 해킹을 성공하기란 거의 불가능할 것 입니다.
뚫는게 '시간 문제'이니 그 시간이 아주아주 문제가 되도록 만들어 버리는 것이죠.
오늘은 이렇게 Hash 가 암호학에서 어떻게 활용되는지 알아 보았습니다.
정리를 해보자면,
Hash 는 단방향적인 암호화 방법이며 고유성과 빠른 처리 속도에서 오는 한계점이 존재하고,
이를 극복하기 위해 Salt 와 Key stretching 이 있다고 할 수 있겠습니다.