이번 문서의 목표: 암호학적 해시 함수가 갖춰야 할 안전성 조건을 설명하고, MAC·HMAC이 무결성을 지키는 원리를 이해하며, 해시·MAC·전자서명이 각각 무결성·인증·부인방지 중 무엇을 제공하는지 정확히 구분할 수 있다.
왜 “요약값”이 필요한가
06편까지는 기밀성(허락된 사람만 읽을 수 있게)을 다뤘다. 그런데 정보보호에는 또 하나의 큰 축이 있다 — “이 데이터가 전송·저장 도중 바뀌지 않았는가”를 확인하는 문제다. 예를 들어 100메가바이트짜리 설치 파일을 다운로드했을 때, 그 파일이 서버에서 나온 것과 한 비트도 다르지 않은지 어떻게 확인할까? 파일 전체를 다시 비교하는 것은 비효율적이다. 대신 파일 전체를 고정된 길이의 짧은 값 하나로 요약해 두고, 그 요약값만 비교하면 된다. 이 요약 기술이 해시 함수(hash function)다.
쉽게 말하면: 해시는 “아무리 큰 파일이라도 항상 같은 길이의 지문(fingerprint)을 만들어내는 함수”다.
암호학적 해시 함수
해시 함수는 임의 길이의 입력을 받아 고정 길이의 출력(해시값, digest 또는 다이제스트라고도 한다)을 내놓는 함수다. 대표적으로 SHA-256(Secure Hash Algorithm, 256비트 출력)이 널리 쓰이며, 과거 표준이던 MD5·SHA-1은 아래에서 설명할 안전성 조건이 깨져 현재는 보안 용도로 사용이 권장되지 않는다.
일반 해시 함수(자료구조에서 배우는 해시테이블용 해시 등)와 달리, 암호학적 해시 함수(cryptographic hash function)는 보안 목적에 쓰이기 위해 다음 세 가지 성질을 반드시 만족해야 한다.
1. 역상 저항성(Preimage Resistance)
해시값 가 주어졌을 때, 를 만족하는 입력 를 찾는 것이 계산적으로 어려워야 한다.
쉽게 말하면: 결과물(지문)만 보고 원본을 거꾸로 알아내지 못해야 한다.
이 성질 덕분에 비밀번호를 데이터베이스에 저장할 때 평문 대신 해시값을 저장할 수 있다 — 해시값이 유출되어도 원래 비밀번호를 역산하기 어렵기 때문이다(다만 짧고 흔한 비밀번호는 미리 계산된 해시표인 레인보우 테이블(rainbow table) 공격에 취약할 수 있어, 실무에서는 솔트(salt, 사용자마다 다른 임의 값을 비밀번호에 덧붙여 해시하는 기법)를 함께 사용한다).
2. 제2역상 저항성(Second Preimage Resistance)
입력 이 주어졌을 때, 를 만족하는 다른 입력 를 찾는 것이 계산적으로 어려워야 한다.
쉽게 말하면: 원본 하나를 이미 알고 있는 상태에서, 그것과 같은 지문을 갖는 “가짜 원본”을 만들어내지 못해야 한다.
3. 충돌 저항성(Collision Resistance)
를 만족하는 서로 다른 두 입력 쌍을 찾는 것이 계산적으로 어려워야 한다. 이를 충돌(collision)이라 부른다.
쉽게 말하면: 아예 처음부터 같은 지문을 갖는 두 개의 서로 다른 문서를 짜맞춰 만들어내지 못해야 한다.
제2역상 저항성과 충돌 저항성의 차이는 시험에서 자주 헷갈리는 지점이다. 제2역상 저항성은 “이미 주어진 특정 입력”과 충돌하는 것을 막는 조건이고, 충돌 저항성은 “임의의 두 입력” 사이의 충돌 자체를 막는 훨씬 강한 조건이다. 일반적으로 충돌 저항성이 성립하면 제2역상 저항성도 성립하지만, 역은 성립하지 않는다.
수학적으로, 출력이 비트인 해시 함수는 입력 가능한 경우의 수가 무한한데 출력 가능한 경우의 수는 개로 유한하므로, 비둘기집 원리(pigeonhole principle, 비둘기 수가 집보다 많으면 반드시 한 집에 두 마리 이상 들어간다는 원리)에 의해 충돌은 반드시 존재한다. 안전성은 “충돌이 없다”가 아니라 “충돌을 찾는 데 현실적인 시간이 걸린다”는 계산적 어려움에 있다는 점을 정확히 이해해야 한다.
메시지 인증 코드(MAC)
해시 함수 단독으로는 무결성만 확인할 수 있을 뿐, 누가 보냈는지는 확인할 수 없다. 예를 들어 공격자가 메시지를 가로채 내용을 바꾸고, 그 바뀐 메시지에 대한 새 해시값을 계산해 함께 보내면, 수신자는 “해시값이 메시지와 일치한다”고 확인할 뿐 그 메시지가 원래 발신자에게서 온 것인지는 알 수 없다. 이 문제를 해결하려면 송신자와 수신자만 아는 비밀키를 해시 계산에 관여시켜야 한다. 이것이 메시지 인증 코드(MAC, Message Authentication Code)다.
쉽게 말하면: 해시가 “지문”이라면 MAC은 “비밀 도장이 찍힌 지문”이다 — 그 비밀 도장(키)이 없으면 아무도 같은 지문을 만들어낼 수 없다.
MAC은 다음과 같이 정의된다.
- : 비밀키 를 사용하는 MAC 생성 함수
- : 원본 메시지
송신자는 메시지 과 함께 값을 전송한다. 수신자는 (송신자와 미리 공유한) 같은 키 로 받은 메시지의 MAC을 직접 계산해, 받은 MAC 값과 비교한다. 두 값이 일치하면 ① 메시지가 변조되지 않았고(무결성), ② 그 키를 가진 사람만 만들 수 있으므로 정당한 송신자가 보낸 것(인증)이 동시에 확인된다.
HMAC: 해시로 만드는 MAC
MAC을 구현하는 대표적인 방법이 HMAC(Hash-based MAC)이다. 이름 그대로 SHA-256 같은 기존 해시 함수를 재료로 삼아 MAC을 만드는 표준 구성 방식이다. 개념적으로는 다음과 같이 이해하면 된다.
- : SHA-256 등의 해시 함수
- : 비밀키 (필요시 해시의 블록 크기에 맞게 패딩됨)
- , : 각각 내부·외부 패딩용으로 정해진 고정 상수 값
- : XOR 연산, : 연접(이어 붙임)
식이 복잡해 보이지만 핵심 아이디어는 단순하다 — 키를 메시지 앞뒤로 두 번(내부·외부) 섞어 해시를 두 번 중첩함으로써, 순수 해시 함수를 키 없이 그대로 쓸 때 발생할 수 있는 특정 확장 공격(length extension attack, 해시값만 보고 원본 뒤에 내용을 이어 붙여도 유효한 새 해시를 만들 수 있는 구조적 약점)을 막는다. 시험 수준에서는 “HMAC = 비밀키 + 해시 함수를 결합해 만든 MAC의 표준 구현”이라는 정의와 목적만 정확히 이해하면 충분하다.
해시·MAC·전자서명 정면 비교
이 세 가지는 모두 “짧은 값으로 무언가를 보증한다”는 점에서 헷갈리기 쉽지만, 각각 보장하는 것이 다르다. 독학사 시험에서 “설명이 맞게 짝지어진 것”을 고르라는 유형으로 자주 나오므로, 이 표를 정확히 암기해야 한다.
| 비교 항목 | 해시(Hash) | MAC(HMAC 등) | 전자서명(Digital Signature) |
|---|---|---|---|
| 사용하는 키 | 없음(키 없이 계산) | 대칭키(송·수신자가 공유하는 비밀키) | 공개키 쌍(서명자의 개인키로 서명, 공개키로 검증) |
| 무결성(변조 여부 확인) | 제공(단, 키가 없어 공격자도 새 해시를 계산할 수 있음) | 제공 | 제공 |
| 인증(누가 만들었는가) | 제공하지 않음 | 제공(단, 키를 공유한 그룹 내 “누군가”까지만 특정 — 그룹 내 누가 보냈는지는 구분 못함) | 제공(개인키 소유자 한 명으로 특정) |
| 부인방지(나중에 발뺌 방지) | 제공하지 않음 | 제공하지 않음 — 키를 공유한 두 사람 모두 같은 MAC을 만들 수 있어 “상대방이 만들었다”고 서로 발뺌 가능 | 제공 — 개인키는 서명자 한 명만 소유 |
| 계산 속도 | 매우 빠름 | 빠름(해시 기반) | 느림(공개키 연산 포함) |
| 대표 예 | SHA-256 | HMAC-SHA256 | RSA 서명, ECDSA |
표에서 가장 자주 출제되는 함정은 MAC의 부인방지 실패다. MAC은 송신자와 수신자가 같은 비밀키를 공유하므로, 수신자도 원리적으로 그 MAC 값을 만들어낼 능력이 있다. 따라서 분쟁이 생겼을 때 제3자(재판, 감사 등)는 “이 메시지를 송신자가 만들었는지 수신자가 만들었는지” 구분할 수 없다 — 이 때문에 MAC은 인증은 제공하되 부인방지는 제공하지 못한다. 반면 전자서명은 개인키를 오직 서명자 한 명만 갖고 있으므로, 검증자(수신자)는 서명을 흉내 낼 수 없고, 따라서 부인방지가 성립한다.
또 하나의 함정은 해시 단독으로는 인증을 전혀 제공하지 못한다는 점이다. 해시는 키가 없는 공개 함수이므로, 공격자가 메시지를 바꾸고 새 해시값을 계산해 함께 보내도 수신자는 구분할 수 없다. “해시값이 같으니 안전하다”는 표현은 무결성 검증 맥락(다운로드 파일이 중간에 손상되지 않았는지)에서만 유효하며, 누가 보냈는지를 확인하는 인증 맥락에서는 무의미하다는 점을 정확히 구분해야 한다.
자주 틀리는 점
- “해시 = MAC”으로 혼동하는 경우 — MAC은 반드시 비밀키가 관여해야 하고, 해시는 키 없이 계산되는 공개 함수다.
- “MAC이 있으면 부인방지도 된다”는 오해 — MAC은 인증까지만 제공하고, 부인방지는 전자서명만 제공한다(키를 공유하는 쌍방 모두가 MAC을 만들 수 있기 때문).
- 충돌 저항성과 제2역상 저항성을 같은 개념으로 착각하는 경우 — 전자는 “임의의 두 입력”, 후자는 “이미 주어진 한 입력과 충돌하는 다른 입력”을 찾는 어려움이라는 점에서 조건의 강도가 다르다.
- “안전한 해시 함수는 충돌이 절대 없다”는 오해 — 비둘기집 원리에 의해 충돌은 수학적으로 반드시 존재하며, 안전성은 그 충돌을 찾기 어렵다는 계산적 난이도에 있다.
핵심 정리
- 암호학적 해시 함수는 역상 저항성·제2역상 저항성·충돌 저항성을 만족해야 하며, 안전성은 “충돌이 없음”이 아니라 “충돌을 찾기 어려움”에 있다.
- MAC은 비밀키를 관여시켜 해시가 제공하지 못하는 인증까지 제공하지만, 키를 공유한 쌍방 모두가 MAC을 생성할 수 있어 부인방지는 제공하지 못한다.
- HMAC은 해시 함수에 비밀키를 두 겹으로 섞어 계산하는 MAC의 표준 구현이다.
- 전자서명은 개인키를 서명자 한 명만 소유하므로 무결성·인증·부인방지를 모두 제공한다 — 해시(무결성만) → MAC(무결성+인증) → 전자서명(무결성+인증+부인방지) 순으로 보장 범위가 넓어진다.