097. 해시 함수 (Hash Function)
⚠️ 이 문서는 임의의 길이를 가진 데이터를 입력받아 고정된 길이의 고유한 '디지털 지문(Digest)'을 뽑아내어 데이터의 무결성을 증명하는, 현대 암호학에서 기밀성(AES)만큼이나 중요한 핵심 축인 '해시 함수'를 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 해시 함수(Hash Function)는 10GB짜리 영화 파일이든 "Hello"라는 짧은 단어든, 믹서기에 넣고 돌리면 항상 정해진 길이(예: 256비트)의 무작위 쓰레기 값(해시값)을 뱉어내는 단방향 수학 함수다.
- 가치: 비밀키가 필요 없으며, 입력값이 단 1비트만 달라져도 완전히 다른 해시값이 튀어나오는 눈사태 효과(Avalanche Effect)를 통해 데이터가 전송 중에 **변조되지 않았음(무결성)**을 완벽하게 증명한다.
- 융합: 해시 함수 자체는 인증(Authentication) 기능이 없으므로, 실무에서는 비밀키를 섞는 HMAC이나 전자서명(RSA)과 융합하여 패스워드 암호화, 블록체인 증명, 파일 무결성 검증 등 IT 인프라 전반의 신뢰를 지탱한다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
내가 친구에게 카카오톡으로 1GB짜리 백업 파일을 보냈을 때, 친구가 받은 파일이 전송 중에 1비트라도 깨지진 않았을까? 혹은 누군가 중간에 악성코드를 몰래 섞어 넣지 않았을까? 이를 확인하기 위해 1GB짜리 원본과 1GB짜리 사본을 1비트씩 통째로 대조하는 것은 미친 짓이다.
이때 필요한 것이 데이터의 **'지문(Fingerprint)'**을 뜨는 기술이다. 경찰이 범인을 잡을 때 사람 통째를 복사해서 비교하지 않고 엄지손가락 지문만으로 식별하듯, 암호학에서는 **해시 함수(Hash Function)**를 통해 1GB짜리 파일을 고작 256비트 크기의 고유한 지문(Digest)으로 압축해 낸다. 친구는 받은 파일의 지문을 스스로 떠본 뒤, 내가 카톡으로 보낸 지문과 일치하는지만 확인하면 100% 파일의 무결성을 확신할 수 있다.
📢 섹션 요약 비유: 해시 함수는 거대한 돼지 한 마리를 통째로 갈아서 조그만 소시지(고정된 길이) 하나를 만드는 마법의 고기 분쇄기입니다. 이 소시지 맛만 보면 원래 돼지가 건강했는지 알 수 있고, 돼지에 소금 1톨만 더 들어가도 소시지 맛이 완전히 달라집니다.
Ⅱ. 암호학적 해시 함수의 3대 필수 조건 (저항성)
일반적인 해시 함수(Java의 hashCode())와 달리, '암호학적(Cryptographic)' 해시 함수로 인정받으려면 해커의 공격을 버티는 3가지 강력한 수학적 저항성(Resistance)을 반드시 가져야 한다.
1. 제1역상 저항성 (Preimage Resistance / 단방향성)
- 개념: 해시값(소시지)이 주어졌을 때, 그것을 갈아 만든 원래의 입력값(돼지)을 수학적으로 역추적해 내는 것이 불가능해야 한다.
- 해커의 공격: 서버가 털려서 해시된 비밀번호
5E884...를 훔쳤을 때, 이를 역산하여 내 원래 비밀번호 "password123"을 알아낼 수 없어야 한다. (즉, $y=H(x)$ 에서 $y$를 알 때 $x$를 구하기 불가능할 것)
2. 제2역상 저항성 (Second Preimage Resistance / 약한 충돌 저항성)
- 개념: 원본 데이터 $x$와 그 해시값 $H(x)$를 모두 알고 있을 때, 해시값이 똑같이 나오는 또 다른 가짜 데이터 $x'$ 를 만들어내는 것이 불가능해야 한다.
- 해커의 공격: 내가 작성한 '100만 원짜리 정상 계약서($x$)'의 해시 지문이
A1B2다. 해커가 이 지문을 유지하면서 내용만 '10억 원($x'$)'으로 교묘하게 위조하려는 시도를 막아야 한다. (즉, $H(x) = H(x')$ 를 만족하는 $x'$ 찾기 불가능)
3. 충돌 저항성 (Collision Resistance / 강한 충돌 저항성)
- 개념: 해커 마음대로 아무 데이터 2개($x_1, x_2$)를 뽑았을 때, 우연히 그 둘의 해시값이 똑같이($H(x_1) = H(x_2)$) 나오는 경우를 찾는 것이 불가능해야 한다. (비둘기집 원리에 의해 언젠가는 충돌이 나지만, 그 시간이 우주 나이보다 길어야 함)
- 해커의 공격: 악성코드 백신은 파일의 해시를 떠서 블랙리스트와 비교한다. 해커가 정상 파일과 해시값이 완벽하게 똑같이 나오는 악성코드 파일을 미리 준비해서 백신을 우회하려는 공격을 막는다. (이게 뚫리면 그 해시 함수는 사망 선고를 받는다.)
┌────────────────────────────────────────────────────────────────────────────────┐
│ 해시 함수의 단방향성과 눈사태 효과 (Avalanche Effect) 시각화 │
├────────────────────────────────────────────────────────────────────────────────┤
│ │
│ [ 원본 데이터 입력 ] [ 해시 함수 (SHA-256) ] │
│ "Hello World" ───────(믹서기 윙윙)──────▶ 3A8B...9F2C │
│ │
│ [ 1비트 변조 데이터 입력 ] │
│ "Hello World." ───────(믹서기 윙윙)──────▶ Z9!P...1Q8@ │
│ (점 하나 찍음) (결과가 완벽히 달라짐) │
│ │
│ [ 역산 시도 (해커) ] │
│ 3A8B...9F2C ───────(거꾸로 돌려!)─────▶ 🚨 역산 절대 불가! │
│ │
│ * 핵심: 마침표 하나 찍었을 뿐인데, 결과물은 단 한 글자도 겹치지 않고 완전히 │
│ 다른 쓰레기 값이 튀어나온다. 이를 통해 1비트의 무결성 훼손도 100% 탐지한다. │
└────────────────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 데이터베이스에 사용자 비밀번호를 저장할 때 평문(Plaintext)으로 저장하면 불법이다. 무조건 해시 함수로 갈아서 해시값만 저장한다. 사용자가 로그인할 때 입력한 비밀번호를 똑같은 해시 함수로 갈아서, DB에 저장된 해시값과 동일한지만 비교한다. 이 구조 덕분에 서버 개발자나 DB 관리자조차도 내 진짜 비밀번호를 영원히 알 수 없는 '단방향 보안'이 완성된다.
- 📢 섹션 요약 비유: 해시 함수는 '과일 쥬스 믹서기'입니다. 사과를 갈면 무조건 사과 쥬스가 나오지만(결정성), 사과 쥬스를 가지고 다시 원래의 사과 모양으로 되돌려 놓을 수는 없습니다(단방향성). 그리고 사과에 소금 한 톨만 섞어 갈아도 쥬스 색깔이 완전히 까맣게 변해버립니다(눈사태 효과).
Ⅲ. 암호학적 해시 알고리즘의 진화 (MD5 $\rightarrow$ SHA)
해커들이 무차별 대입(Brute Force)이나 생일 공격(Birthday Attack)으로 '충돌'을 찾아내는 컴퓨터 속도가 빨라지면서, 믹서기의 날도 점점 정교하고 길어져야 했다.
- MD5 (Message Digest 5): 128비트 길이. 1996년 치명적인 충돌 결함이 발견되어 현재는 파일 체크섬(단순 오류 확인용) 외에는 보안용으로 절대 금지됨.
- SHA-1 (Secure Hash Algorithm 1): 160비트 길이. 오랫동안 인증서 표준이었으나, 2017년 구글이 SHAttered 공격으로 동일한 해시값을 가지는 두 개의 PDF 파일을 찾아내면서 사망 선고를 받았다.
- SHA-2 (SHA-256, SHA-512): 현재 인터넷(TLS, 블록체인 비트코인 등)을 지배하는 가장 완벽한 표준. 아직까지 수학적 충돌이 단 한 건도 발견되지 않았다.
- SHA-3 (Keccak): SHA-2가 털릴 만일의 사태에 대비해, 아예 내부 작동 방식(스폰지 구조)을 갈아엎어 예비용으로 만들어둔 차세대 표준.
Ⅳ. 실무적 한계: 레인보우 테이블과 솔트(Salt)
해시 함수는 단방향이라 안전하지만, 비밀번호를 지키기엔 치명적 약점이 있다. 속도가 너무 빠르다는 것이다.
해커는 123456, password 같은 흔한 비밀번호 10억 개를 미리 해시 믹서기에 돌려서 **[평문 = 해시값]**의 거대한 짝짜꿍 사전(레인보우 테이블)을 만들어둔다. DB를 해킹해 해시값을 훔친 뒤, 이 사전에서 Ctrl+F 로 찾으면 순식간에 평문이 털린다.
- 실무 방어 대책 (Salt & Key Stretching):
- 비밀번호를 해시하기 전에, 사용자마다 랜덤한 쓰레기 문자열(솔트, Salt)을 비번 앞뒤에 붙인다. (
password$\rightarrow$x9!#password) - 해커가 만든 레인보우 테이블이 휴지조각이 된다. 여기에 더해 믹서기를 한 번만 돌리지 않고 10만 번씩 돌려버리는(Key Stretching, 예:
Bcrypt,PBKDF2,Argon2) 짓을 해야만 진짜 안전한 비밀번호 저장이 완성된다.
- 비밀번호를 해시하기 전에, 사용자마다 랜덤한 쓰레기 문자열(솔트, Salt)을 비번 앞뒤에 붙인다. (
Ⅴ. 결론
"암호화가 남의 눈을 가리는 마스크라면, 해시 함수는 남의 손길을 거부하는 봉인(Seal)이다." 해시 함수는 복호화 기능이 없다는 태생적 결함(단방향)을 가장 강력한 무기(무결성 증명)로 승화시킨 천재적인 발명품이다. 아무리 크고 방대한 데이터라도 256비트라는 작은 거울에 그 영혼을 완벽히 비추어 담아내며, 오늘날 소프트웨어 무결성 검증, 디지털 서명, 그리고 비트코인의 작업 증명(PoW)까지 IT 세상의 신뢰를 담보하는 가장 단단한 주춧돌로 군림하고 있다.
📌 관련 개념 맵
- 해시의 3대 저항성: 제1역상 저항성, 제2역상 저항성, 충돌 저항성
- 대표 알고리즘: MD5 (사망) $\rightarrow$ SHA-1 (사망) $\rightarrow$ SHA-2 (표준) $\rightarrow$ SHA-3 (미래 차세대)
- 해시 해킹 기법: 레인보우 테이블 공격, 생일 공격(Birthday Attack, 충돌 찾기)
- 안전한 패스워드 방어법: 솔트(Salt), 키 스트레칭(Bcrypt, PBKDF2)
👶 어린이를 위한 3줄 비유 설명
- 100페이지짜리 긴 편지를 친구에게 보낼 때, 도둑이 중간에 한 글자라도 바꿨는지 확인하고 싶어요.
- 그래서 편지를 '해시 함수'라는 믹서기에 넣고 돌렸더니,
A9!#라는 짧고 엉뚱한 4글자 지문(해시값)이 튀어나왔어요. 이 지문을 편지 겉면에 적어서 보내요. - 도둑이 몰래 편지에서 마침표 하나만 지워도, 친구가 받은 편지를 다시 믹서기에 넣으면
Z8@&라는 완전히 다른 지문이 나오기 때문에 단번에 도둑의 장난을 알아채는 완벽한 거짓말 탐지기랍니다!