Hash 함수의 핵심 특징
- 해시 함수의 가장 중요한 특징은 단방향성(One-Way function)입니다. 이는 함수 f(x) = y 일 때, 입력값 x로부터 결과값 y를 쉽게 계산할 수 있지만, 결과값 y만으로는 원본 입력값 x를 역으로 추론하거나 복원하기가 매우 어렵다
단방향성의 이해
- 간단한 예로 ‘나머지 연산(Modulo operation)’을 들 수 있다
7÷5=1 (몫),2 (나머지)
- 여기서 나머지 값 ‘2’만으로는 원본 숫자 ‘7’을 정확히 알 수 없다. 5로 나누어 나머지가 2가 되는 숫자는 7, 12, 17 등 무수히 많기 때문이다. 이처럼 해시 함수는 원본 정보의 일부를 의도적으로 유실시키는 방식으로 단방향성을 구현하여 원본 복구를 어렵게 만든다
고정된 결과값 길이
- 입력값의 크기(길이)와 관계없이 해시 함수의 결과값(해시 값)의 길이는 항상 일정한다. 이는 나머지 연산에서 결과값의 범위가 나누는 수의 의해 제한되는 것과 유사하다. 예를 들어 5로 나눈 나머지 값은 항상 0부터 4 사이의 값으로 고정된다. 암호학에서는 이처럼 고정된 범위 내에서 다양한 결과가 나올 수 있도록 설계된 해시 함수가 중요하게 사용된다
데이터 무결성 확보
해시 함수의 주된 용도 중 하나는 데이터 무결성(Data Integrity) 확보이다. 데이터 무결성은 데이터가 전송되거나 저장되는 과정에서 변조되거나 위조되지 않았음을 증명하는 것을 의미한다. 해시는 Checksum보다 훨씬 강력한 방식으로 데이터 무결성을 보장한다
- Checksum Vs Hash: Checksum은 데이터의 오류를 검출하는 데 사용되지만, 의도적인 변조에는 취약하다. 반면 해시는 단방향성과 충돌 회피성(입력값이 조금만 달라져도 해시 값이 완전히 달라진다) 덕분에 변조를 훨씬 효과적으로 감지할 수 있다
좋은 해시 알고리즘의 조건
- 충돌 회피(Collision Resistance): 서로 다른 입력값에 대해 동일한 해시 값이 나올 확률(충돌)이 매우 낮아야 한다
- 고른 분포: 해시 값들이 특정 범위 내에 고르게 분포되어야 한다
- 빠른 계산속도: 해시 값을 효율적으로 계산할 수 있어야 한다
- Avalanche Effect (눈사태 효과): 입력값의 1비트만 변경되어도 해시 값의 약 50%가 변경되어야 한다
- 선상(Pre-image) 저항성: 주어진 해시 값 h 에 대해 h = hash(m)인 메시지 m을 찾기 어려워야한다
- 제2 선상(Second pre-image) 저항성: 주어진 메시지 m1에 대한 hash(m1) = hash(m2)인 다른 메시지 m2를 찾기 어려워야 한다
대표적인 해시 알고리즘
주로 MD(Message Digest) 계열과 SHA(Secure Hash Algorithm) 계열이 있다
- MD-5: 과거에 널리 사용되었으나, 보안 취약점(충돌 가능성 높음)이 발견되어 패스워드 암호화와 같은 보안이 중요한 용도에는 사용이 권장되지 않는다
- SHA 계열
- SHA-1: MD-5와 유사하게 보안 취약점이 발견되어 사용이 지양된다
- SHA-2 (SHA-256, SHA-512 등): 현재 널리 사용되는 알고리즘으로, 숫자가 클수록 해시 값의 길이가 길어져 더 높은 보안성을 제공한다 (예: SHA-256은 256비트 길이의 해시 값을 생성)
- SHA-3: SHA-2의 취약점 발견에 대비해 2015년 표준화된 최신 해시 알고리즘으로, 완전히 다른 내부 구조(Keccak 스펀지 구조)를 사용한다
- bcrypt: 계산 비용 조절 가능, Salt 자동 생성
- scrypt: 메모리 집약적 설계로 GPU/ASIC 공격 저항성 강화
해시 함수의 활용 예시
- 이미지에 제시된 MD-5 해시 결과는 ‘TestString’이라는 짧은 문자열이 MD-5 함수를 거쳐 ‘MrRq3uWeS1…’와 같이 긴 해시 값으로 변환된다. 이처럼 입력값의 길이에 상관없이 해시 값의 길이는 항상 일정하며, 이 해시 값만으로는 원본 문자열 ‘TestString’을 역으로 복원하는 것이 불가능하다
패스워드 단방향 암호화와 Salt
사용자 인증 시 패스워드를 결코 평문(읽을 수 있는 그대로의 문자열)으로 데이터베이스에 저장해서는 안 된다. 해킹이나 내부자에 의한 유출 시 심각한 보안 문제가 발생하기 떄문이다. 따라서 패스워드는 해시 함수를 이용해 단방향으로 암호화하여 저장한다
- 문제점: 해시 함수를 사용하더라도, ‘레인보우 테이블‘ 공격이나 ‘무작위 대입 공격(Brute Force Attack)‘을 통해 해시 값에 해당하는 원본 패스워드를 찾아낼 수 있다. 특히 MD-5처럼 해시 값의 길이가 짧고 충돌 가능성이 높은 알고리즘은 이러한 공격에 매우 취약하다
- Salt(솔트)의 도입: 이러한 취약점을 보완하기 위해 ‘Salt(솔트)’라는 무작위 값을 사용한다
- 원리: 사용자가 입력한 패스워드에 미리 정의된 임의의 Salt 값을 추가(예: Salt + 패스워드)하여 함께 해시한다
- 효과: 같은 패스워드에 미리 패스워드라도 매번 다른 해시 값이 생성된다. 이로 인해 공격자가 미리 계산해둔 해시 값(레인보우 테이블)을 사용하기 어렵게 만들며, 무작위 대입 공격의 효율성도 크게 떨어뜨려 패스워드 보안을 강화한다. Salt 값은 대개 각 사용자마다 다르게 생성되어 패스워드 해시 값과 함께 저장된다
- Salt는 사용자마다 고유하게 생성되며. 일반적으로 암호학적으로 안전한 난수 생성기(CSPRNG)를 사용한다. Salt는 비밀 정보가 아니므로 해시 값과 함께 평문으로 데이터베이스에 저장해도 안전하다
해시 기술의 다양한 활용처
- 데이터 무결성 확보: 파일의 무결성 검증 (예: 다운로드된 파일이 원본과 동일한지 확인), 디지털 포렌식(데이터 변조 여부 확인), 인증서 검증 등에 사용된다
- 패스워드 단방향 암호화: 패스워드를 안전하게 저장하는 데 필수적이다
- 블록체인: 블록체인의 핵심 기술 중 하나이다. 각 블록에는 이전 블록의 해시 값이 포함되어 있어, 어느 한 블록의 데이터가 변조되면 그 이후의 모든 블록의 해시 값이 변경되어 전체 체인의 무결성이 깨지게 된다. 이는 데이터 변조를 사실상 불가능하게 하여 블록체인의 신뢰성을 확보하는 근간이 된다
- 디지털 서명: 해시와 공개키 기반 구조(PKI) 기술을 결합하여 문서의 위변조 여부와 서명자의 신원을 확인할 수 있다