11장. 암호학적 해시 함수
학습 목표
- 암호학적 해시 함수의 응용을 요약한다.
- 메시지 인증에 사용되는 해시 함수가 왜 보호되어야 하는지 설명한다.
- Preimage resistant, Second preimage resistant, Collision resistant 속성의 차이를 이해한다.
- 암호학적 해시 함수의 기본 구조를 개관한다.
- CBC를 이용한 해시 함수 구성을 설명한다.
- SHA-512의 동작을 이해한다.
- 생일 역설과 생일 공격의 개요를 이해한다.
11.1 암호학적 해시 함수의 응용
해시 함수 는 가변 길이 데이터 블록 을 받아 고정 길이 해시값 을 생성한다. 의 어떤 비트가 변경되면 높은 확률로 도 변경된다.
암호학적 해시 함수란, (a) 사전 지정된 해시 결과에 매핑되는 데이터를 찾거나 (b) 같은 해시 결과를 내는 두 데이터를 찾는 것이 계산적으로 불가능한 알고리즘이다.
메시지 인증
메시지의 무결성을 검증하는 메커니즘. 송신자가 을 계산하여 메시지와 함께 전송, 수신자가 재계산하여 비교한다. 해시값은 반드시 보호되어야 한다 — 그렇지 않으면 공격자가 메시지와 해시값을 함께 변조할 수 있다.
해시코드로 인증을 제공하는 네 가지 방식:
| 방식 | 설명 |
|---|---|
| (a) 대칭 암호화 (전체) | — 기밀성 + 인증 |
| (b) 대칭 암호화 (해시만) | — 인증만 (기밀성 불필요 시) |
| (c) 비밀값 결합 | — 암호화 없이 인증 (공유 비밀값 사용) |
| (d) 비밀값 + 암호화 | — 인증 + 기밀성 |
키 기반 해시 함수로, 비밀키 와 메시지 을 입력으로 받아 고정 길이 인증자(태그)를 생성한다. 은 사실상 MAC의 한 형태이다. 실제로는 전용 MAC 알고리즘이 암호화 알고리즘보다 더 효율적이다. MAC은 12장에서 다룬다.
전자서명
메시지의 해시값을 송신자의 개인키로 암호화하여 서명한다.
- (a) — 인증 + 서명
- (b) — 인증 + 서명 + 기밀성 (일반적 기법)
기타 응용
- 일방향 비밀번호 파일: 비밀번호의 해시만 저장 → 원문 비노출
- 침입 탐지 / 바이러스 탐지: 파일의 를 안전하게 저장, 변조 시 감지
- PRF/PRNG: 해시 기반 의사난수 함수 구성 (대칭키 생성 등)
11.2 두 가지 단순 해시 함수
비트별 XOR (종단 중복 검사)
비트 해시코드의 각 비트 위치에 대한 단순 패리티. 랜덤 데이터에는 효과적이나 ( 확률로 오류 미탐지), 규칙적 데이터(예: ASCII의 최상위 비트가 항상 0)에서는 효과가 감소한다.
회전 XOR (RXOR)
각 블록 처리 후 해시값을 1비트 순환 시프트(rotate) 한 뒤 XOR. 입력을 더 잘 "랜덤화"하지만, 암호화된 해시코드가 평문 메시지와 함께 전송될 때 — 대체 메시지를 쉽게 생성 가능하므로 보안 용도로는 부적합하다.
메시지 블록 의 XOR을 해시코드로 사용하고 CBC 모드로 전체를 암호화하면, CBC의 정의에 의해 해시코드는 다음과 같이 분해된다:
각 항을 어떤 순서로든 XOR할 수 있으므로, 암호문 블록의 순서를 바꿔도 해시코드가 변하지 않는다.
11.3 보안 요구사항
용어 정의
- 원상 (Preimage): 일 때 는 의 원상. 는 다대일 함수이므로 하나의 해시값에 여러 원상이 존재한다.
- 충돌 (Collision): 이면서 .
해시코드가 비트이고 입력이 비트()이면, 각 해시값은 평균 개의 원상을 가진다.
보안 요구사항
| 요구사항 | 설명 |
|---|---|
| 가변 입력 크기 | 임의 크기 데이터에 적용 가능 |
| 고정 출력 크기 | 고정 길이 출력 생성 |
| 효율성 | 계산이 쉬움 (하드웨어·소프트웨어 모두 실용적) |
| Preimage resistant (일방향성) | 해시값 가 주어졌을 때 인 를 찾기 불가능 |
| Second preimage resistant | 블록 가 주어졌을 때 인 를 찾기 불가능 |
| Collision resistant | 인 임의의 쌍 , 를 찾기 불가능 |
| 의사난수성 | 출력이 표준 의사난수 테스트를 통과 |
처음 다섯 속성을 만족하면 약한 해시 함수(weak hash function), 여섯 번째까지 만족하면 **강한 해시 함수(strong hash function)**라 한다.
Collision resistant → Second preimage resistant (역은 불성립). Collision resistant와 Preimage resistant는 서로 독립적이다.
응용별 요구 속성
| 응용 | Preimage | Second Preimage | Collision |
|---|---|---|---|
| 해시 + 전자서명 | Yes | Yes | Yes* |
| 침입 탐지 / 바이러스 탐지 | Yes | ||
| 일방향 비밀번호 파일 | Yes | ||
| MAC | Yes | Yes | Yes* |
* 공격자가 선택 메시지 공격을 수행할 수 있는 경우
무차별 대입 공격
비트 해시코드에 대한 무차별 공격 비용:
| 공격 유형 | 비용 |
|---|---|
| Preimage / Second preimage | |
| Collision | (생일 역설) |
생일 역설과 생일 공격
부터 까지의 균등 분포에서 랜덤으로 값을 뽑을 때, 개를 뽑으면 반복 원소(충돌)가 나타날 확률이 를 초과한다. 비트 해시의 경우 시도.
Yuval의 생일 공격 전략:
- 송신자 A가 정당한 메시지 에 서명할 준비를 한다.
- 공격자가 의 개 변형을 생성하고 해시값을 저장한다.
- 공격자가 위조 메시지 를 준비하고, 의 변형 를 생성하며 인 쌍을 찾을 때까지 반복한다.
- 합법적 변형 을 A에게 제시하여 서명을 받고, 그 서명을 위조 변형 에 부착한다.
128비트 해시에 대한 충돌 탐색 비용은 에 불과하다. 1천만 달러짜리 전용 머신으로 MD5(128비트) 충돌을 24일만에 발견할 수 있다는 설계가 제시되었다. 따라서 128비트는 불충분하고, 160비트도 현재 의심되며, 256비트 이상이 권장된다.
암호분석과 반복 해시 함수 구조
대부분의 해시 함수는 반복(iterated) 해시 함수 구조를 사용한다 (Merkle-Damgård):
메시지 을 개의 비트 블록 으로 분할하고, 압축 함수 를 반복 적용한다.
길이 필드가 입력에 포함되고, 압축 함수 가 충돌 저항이면, 결과적인 반복 해시 함수도 충돌 저항이다. 따라서 안전한 해시 함수 설계 문제는 고정 크기 입력에 대한 충돌 저항 압축 함수 설계 문제로 환원된다.
11.4 CBC 기반 해시 함수
비밀키 없이 CBC 기법을 사용하여 해시 함수를 구성하는 방법:
DES를 사용하면 64비트 해시코드만 생성 → 생일 공격에 취약. 더구나 단일 메시지·서명 쌍만으로도 meet-in-the-middle 공격이 가능하다:
- 원하는 메시지 를 구성하고 까지 계산
- 개의 랜덤 블록 에 대해 를 계산
- 개의 랜덤 블록 에 대해 를 계산
- 인 쌍을 찾음 (생일 역설)
- 가 원본과 동일한 해시코드 를 가짐
Davies-Price 변형 이나 Meyer 변형 등이 제안되었으나, 모두 다양한 공격에 취약한 것으로 밝혀졌다.
11.5 SHA (Secure Hash Algorithm)
SHA 패밀리
NIST가 개발. 거의 모든 다른 표준화된 해시 함수가 심각한 약점을 가진 것으로 밝혀지면서, SHA가 사실상 유일한 표준이 되었다.
| 알고리즘 | 메시지 크기 | 블록 크기 | 워드 크기 | 다이제스트 크기 |
|---|---|---|---|---|
| SHA-1 | 512 | 32 | 160 | |
| SHA-224 | 512 | 32 | 224 | |
| SHA-256 | 512 | 32 | 256 | |
| SHA-384 | 1024 | 64 | 384 | |
| SHA-512 | 1024 | 64 | 512 | |
| SHA-512/224 | 1024 | 64 | 224 | |
| SHA-512/256 | 1024 | 64 | 256 |
(모든 크기: 비트 단위)
SHA-1은 연산으로 충돌을 찾을 수 있음이 발표 (이론적 한계 보다 훨씬 적음) → 단계적 폐지, SHA-2 사용 권장.
SHA-512 처리 과정
Step 1 — 패딩: 메시지 길이 가 되도록 패딩. 항상 추가 (이미 원하는 길이여도). 1비트 + 필요한 수의 0비트로 구성.
Step 2 — 길이 추가: 128비트 블록으로 원본 메시지의 비트 길이를 추가.
Step 3 — 해시 버퍼 초기화: 8개의 64비트 레지스터 를 처음 8개 소수의 제곱근의 소수 부분에서 추출한 상수로 초기화.
Step 4 — 80라운드 처리: 각 1024비트 블록 에 대해:
여기서 는 8개 워드 각각에 대한 덧셈.
SHA-512 라운드 함수
각 라운드 ()에서:
그 후 레지스터를 이동: , , , , , , , .
여기서:
메시지 스케줄
처음 16개 워드 는 현재 메시지 블록에서 직접 취한다. 나머지는:
80라운드 처리 후, 해시코드의 모든 비트는 입력의 모든 비트의 함수이다. 충돌 발견 난이도는 , 원상 발견 난이도는 으로 추정된다.
예시: "abc"의 SHA-512 해시
24비트 입력 01100001 01100010 01100011을 872비트 패딩 + 128비트 길이 필드로 1024비트 블록을 구성한 뒤 80라운드를 처리하면:
ddaf35a193617aba cc417349ae204131 12e6fa4e89a97ea2 0a9eeee64b55d39a
2192992a274fc1a8 36ba3c23a3feebbd 454d4423643ce80e 2a9ac94fa54ca49f
"abc"를 "cbc"로 1비트 변경하면 해시의 253비트가 달라진다 (전체 512비트의 약 절반) — 우수한 눈사태 효과(avalanche effect).
11.6 SHA-3
배경
SHA-1은 MD4/SHA-0과 구조가 유사하여 취약점이 우려되었고, SHA-2도 같은 구조·수학 연산을 공유한다. NIST는 2007년 SHA-3 공모를 시작하여 2012년 Keccak 알고리즘을 SHA-3로 선정했다 (FIPS 202, 2015).
스펀지 구조 (Sponge Construction)
SHA-3의 핵심 구조. 세 가지 파라미터로 정의된다:
- — 각 입력 블록을 처리하는 내부 함수
- — 입력 블록 크기 (비트율, bitrate)
- — 패딩 알고리즘
상태 변수 는 비트로 구성되며 (: 용량, capacity), 0으로 초기화된다.
흡수 단계 (Absorbing phase):
각 반복에서 입력 블록 를 비트로 확장 (), 상태 와 XOR한 뒤, 내부 함수 를 적용한다.
추출 단계 (Squeezing phase):
해시 길이 이면 흡수 단계 완료 후 의 상위 비트를 반환하고 종료. 이면 를 추가로 적용하며 비트씩 추출하여 연결한다.
스펀지 구조의 보안은 **용량 **에 의존한다. 충돌 저항은 , 원상 저항은 이다. 구현 시 비트율 을 늘려 속도를 높이거나 용량 를 늘려 보안을 강화할 수 있다.
SHA-3 파라미터
| 다이제스트 크기 | 비트율 | 용량 | 라운드 수 | 충돌 저항 | 원상 저항 |
|---|---|---|---|---|---|
| 224 | 1152 | 448 | 24 | ||
| 256 | 1088 | 512 | 24 | ||
| 384 | 832 | 768 | 24 | ||
| 512 | 576 | 1024 | 24 |
기본값: 비트 (Keccak-f[1600]).
SHA-3 반복 함수 (Keccak-f)
1600비트 상태를 의 3차원 배열 로 취급한다. 64비트 단위를 레인(lane) 라 한다.
24라운드를 수행하며, 각 라운드는 다섯 단계의 합성으로 구성된다:
| 단계 | 유형 | 설명 |
|---|---|---|
| 치환 | 각 비트를 자신 + 인접 두 열의 XOR로 갱신 → 확산 | |
| 순열 | 각 레인 내에서 서로 다른 양만큼 순환 비트 시프트 | |
| 순열 | 행렬 내에서 레인의 위치 이동 | |
| 치환 | 각 비트를 같은 행의 다음 두 레인 비트의 함수로 갱신 → 유일한 비선형 단계 | |
| 치환 | 에 라운드 상수 을 XOR → 대칭성 파괴 |
단계
여기서 . 각 비트의 갱신값은 11개 비트에 의존하여 우수한 확산을 제공한다.
단계
은 변경 없이, 나머지 24개 레인은 각각 서로 다른 양만큼 순환 시프트된다. 시프트량은 로 결정된다.
단계
같은 대각선에 있던 레인들이 같은 행으로 모이는 순열이다.
단계
이것이 유일한 비선형 매핑이다. 이 단계 없이는 라운드 함수가 선형이 된다.
단계
24개의 64비트 라운드 상수가 사용되며, 해밍 무게는 1~6이다. 와 를 통해 의 변화가 1라운드 만에 모든 레인으로 확산된다.
모든 연산이 비트 단위 부울 연산(XOR, AND, NOT)과 순환 시프트에 한정된다. 테이블 참조, 산술 연산, 데이터 의존적 시프트가 없으므로 하드웨어·소프트웨어 양쪽에서 효율적으로 구현 가능하며, 트랩도어를 숨길 수 없다.
주요 용어
| 한글 | 영문 |
|---|---|
| 흡수 단계 | absorbing phase |
| 생일 공격 | birthday attack |
| 생일 역설 | birthday paradox |
| 비트율 | bitrate |
| 용량 | capacity |
| 충돌 저항 | collision resistant |
| 압축 함수 | compression function |
| 암호학적 해시 함수 | cryptographic hash function |
| 해시코드 / 해시값 | hash code / hash value |
| 키 기반 해시 함수 | keyed hash function |
| 레인 | lane |
| 메시지 다이제스트 | message digest |
| 원상 저항 | preimage resistant |
| 제2원상 저항 | second preimage resistant |
| 스펀지 구조 | sponge construction |
| 추출 단계 | squeezing phase |
| SHA-1 / SHA-2 / SHA-3 | SHA-1 / SHA-2 / SHA-3 |