해시 함수는 소프트웨어 개발 곳곳에 있습니다. 여러분이 인식하지 못하더라도요. 파일을 다운로드하고 체크섬을 확인할 때마다, 웹사이트에 로그인할 때마다, Git 커밋을 할 때마다, 비트코인을 채굴할 때마다(음, 마지막 건 아마 아닐 거예요), 해시 함수가 뒤에서 무거운 짐을 지고 있습니다.
해시 함수가 무엇인지, 어떻게 다른지, 언제 어떤 것을 사용해야 하는지 알아봅시다.
해시 함수란?
해시 함수는 어떤 입력이든 — 단일 문자, 소설, 4GB 비디오 파일 — 받아서 "해시" 또는 "다이제스트"라고 불리는 고정 크기의 출력을 생성합니다. 데이터의 지문이라고 생각하면 됩니다. 입력이 아무리 크거나 작아도 출력은 항상 같은 길이입니다.
해시 함수를 특별하게 만드는 것들:
- 결정적: 같은 입력은 항상 같은 출력을 생성합니다.
hash("hello")는 어떤 머신에서든, 어떤 프로그래밍 언어에서든 매번 같은 값을 반환합니다. - 일방향: 출력에서 입력을 역산할 수 없습니다. 해시가 주어져도 그것을 생성한 것이 무엇인지 알아낼 방법이 없습니다(추측하는 것 외에는). 이것이 비밀번호 저장에 유용한 이유입니다.
- 눈사태 효과: 입력의 한 비트만 바꿔도 출력이 극적으로 변합니다. 예를 들어, "hello"와 "Hello"의 SHA-256 해시는 완전히 다른 문자열입니다.
- 충돌 저항성: 같은 해시 출력을 생성하는 두 개의 서로 다른 입력을 찾는 것이 실질적으로 불가능해야 합니다. 알고리즘이 강할수록 충돌을 찾기가 더 어렵습니다.
실제로 확인해 봅시다:
단 한 글자만 다른 입력에서 완전히 다른 출력이 나옵니다 — 소문자 "h" 대 대문자 "H". 이것이 눈사태 효과의 실제 모습입니다.
해시 함수의 내부 동작 원리
해시 함수 뒤의 수학은 복잡하지만, 전반적인 과정은 간단합니다. 대부분의 해시 함수는 다음 단계를 따릅니다:
1. 패딩: 입력 메시지가 고정된 블록 크기의 배수가 되도록 패딩됩니다(예: SHA-256의 경우 512비트). 이렇게 하면 알고리즘이 데이터를 균일한 청크로 처리할 수 있습니다.
2. 블록 분할: 패딩된 메시지가 고정 크기 블록으로 나뉩니다.
3. 압축 라운드: 각 블록은 여러 라운드의 비트 연산을 통해 처리됩니다 — XOR, AND, OR, 비트 시프트, 모듈러 덧셈. 이러한 연산들이 비트를 철저하게 섞어서 모든 출력 비트가 모든 입력 비트에 의존하게 됩니다.
4. 체이닝: 한 블록의 처리 출력이 다음 블록의 처리에 입력됩니다. 그래서 입력 초반의 아주 작은 변경도 이후 모든 블록에 연쇄적으로 영향을 미칩니다.
5. 최종 다이제스트: 모든 블록이 처리된 후, 내부 상태가 최종 해시 값으로 출력됩니다.
핵심은 이러한 연산들이 정방향으로는 쉽게 계산할 수 있지만 역방향으로는 실질적으로 불가능하다는 것입니다. 비트를 "역혼합"하여 원래 입력을 복구할 수 없습니다.
MD5: 은퇴한 베테랑
MD5는 1991년 Ronald Rivest가 설계했으며 128비트(16진수 32자) 해시를 생성합니다. 수십 년간 표준이었습니다 — 인터넷의 모든 파일 다운로드 옆에 MD5 체크섬이 있었죠.
하지만 MD5는 이제 암호학적으로 깨진 것으로 간주됩니다. 연구자들은 실용적인 충돌 공격을 시연했습니다 — 즉, 같은 MD5 해시를 생성하는 두 개의 서로 다른 파일을 만들 수 있다는 뜻입니다. 2008년 연구자들은 MD5 충돌을 이용해 위조 SSL 인증서를 만들어, 이것이 단순한 이론적 약점이 아님을 증명했습니다.
아직 괜찮은 용도: 파일 무결성 검사(다운로드가 올바르게 완료되었는지 확인), 중복 제거용 체크섬, 비보안 해시 테이블, 보안이 중요하지 않은 빠른 데이터 핑거프린팅.
절대 사용 불가: 비밀번호 저장, 디지털 서명, 보안 인증서, 또는 누군가가 의도적으로 충돌을 만들 수 있는 모든 경우.
SHA-1: 역시 은퇴
SHA-1은 NSA가 설계하고 1995년에 발표했습니다. 160비트(16진수 40자) 해시를 생성합니다. 수년간 SSL 인증서, PGP 서명, 버전 관리 시스템의 표준이었습니다.
구글이 2017년에 실용적인 충돌 공격을 시연(유명한 SHAttered 공격)한 후 폐기되었습니다. 그들은 같은 SHA-1 해시를 가진 두 개의 서로 다른 PDF 파일을 만들었습니다. 이 공격에는 9,223,372,036,854,775,808번의 SHA-1 계산이 필요했습니다 — 엄청나지만, 현대 클라우드 컴퓨팅 자원으로는 실현 가능합니다.
Git은 내부적으로 커밋 해시에 SHA-1을 여전히 사용하지만, SHA-256으로 전환 중입니다. 브라우저와 인증 기관은 수년 전에 SHA-1 인증서 수락을 중단했습니다. 오늘날 어떤 코드베이스에서든 SHA-1이 보안 용도로 사용되고 있다면, 표시하고 마이그레이션해야 합니다.
SHA-256과 SHA-512: 현재의 표준
이들은 NSA가 설계하고 2001년에 발표한 SHA-2 패밀리의 일부입니다. 오늘날 대부분의 용도에 사용해야 할 것들입니다.
- SHA-256: 256비트 출력(16진수 64자). 비트코인, TLS 인증서, 대부분의 보안 애플리케이션에서 사용됩니다. 보안과 성능의 최적 균형점입니다. 비트코인의 전체 작업 증명 시스템은 이중 SHA-256 해싱을 기반으로 구축되어 있습니다.
- SHA-512: 512비트 출력(16진수 128자). 더 큰 출력은 더 강한 충돌 저항성을 의미합니다. 흥미롭게도 SHA-512는 64비트 프로세서에서 SHA-256보다 더 빠른 경우가 많습니다. 64비트 워드로 네이티브하게 동작하기 때문이며, SHA-256은 32비트 워드를 사용합니다.
- SHA-384와 SHA-512/256: 이들은 SHA-512의 잘린 변형입니다. SHA-384는 384비트 출력을, SHA-512/256은 256비트 출력을 제공하지만 SHA-512의 64비트 연산의 성능 이점을 가집니다.
빠른 비교:
SHA-3: 차세대
SHA-3는 NIST가 주관한 공개 경쟁 후 2015년에 표준화되었습니다. Merkle-Damgard 구조를 사용하는 SHA-2와 달리, SHA-3는 Keccak 스펀지 구조를 기반으로 합니다 — 근본적으로 다른 설계입니다.
왜 이것이 중요할까요? 만약 수학적 돌파구가 SHA-2의 설계 접근 방식을 손상시킨다면, SHA-3는 완전히 다른 방식으로 작동하기 때문에 영향을 받지 않습니다. 암호학 커뮤니티를 위한 보험 정책인 셈입니다.
SHA-3는 같은 출력 크기로 제공됩니다 — SHA3-256, SHA3-384, SHA3-512 — 그리고 SHAKE128과 SHAKE256도 도입하는데, 이는 원하는 길이의 해시를 생성할 수 있는 "확장 가능한 출력 함수"입니다.
실제로는 SHA-2가 여전히 더 널리 사용되고 대부분의 하드웨어에서 더 빠릅니다. SHA-3 채택이 늘고 있지만, 대체라기보다는 백업 표준에 가깝습니다.
실제 사용 사례
Git 버전 관리: Git의 모든 커밋, 트리, 블롭은 SHA-1 해시로 식별됩니다. git commit을 실행하면, Git은 변경 내용, 트리 구조, 부모 커밋 해시, 작성자 정보, 타임스탬프를 해싱합니다. 커밋 해시가 a1b2c3d4e5f6...처럼 보이는 이유가 바로 이것입니다 — 말 그대로 SHA-1 다이제스트입니다.
비트코인 채굴: 채굴자들은 블록 데이터와 결합하여 이중 SHA-256으로 해싱했을 때 목표 임계값 이하의 해시를 생성하는 논스 값을 찾기 위해 경쟁합니다. 이 해시를 찾는 난이도가 전체 네트워크를 보호합니다. 2024년 기준, 비트코인 네트워크는 초당 약 500경 개의 SHA-256 해시를 계산합니다.
파일 중복 제거: Dropbox 같은 클라우드 스토리지 서비스는 업로드하는 모든 파일을 해싱합니다. 해시가 기존 파일과 일치하면 중복을 저장하지 않고 포인터만 추가합니다. 이렇게 해서 막대한 양의 스토리지를 절약합니다.
디지털 서명: 문서나 소프트웨어 릴리스에 서명할 때, 전체 파일에 서명하는 것이 아닙니다. 대신, 파일을 해싱하고 그 해시를 개인 키로 서명합니다. 수신자는 파일을 직접 해싱하고 그 해시에 대해 서명을 검증합니다.
API 인증: HMAC(해시 기반 메시지 인증 코드)는 비밀 키와 메시지 해시를 결합하여 API 요청의 무결성과 진위를 모두 검증합니다. AWS, Stripe, 그리고 대부분의 주요 API가 요청 서명에 HMAC-SHA256을 사용합니다.
개발자가 해싱에서 흔히 저지르는 실수
비밀번호에 해시 함수 사용: 일반 SHA-256은 비밀번호 해싱에 너무 빠릅니다. GPU를 가진 공격자는 초당 수십억 개의 SHA-256 해시를 계산할 수 있어 무차별 대입 공격이 쉬워집니다. 항상 bcrypt, scrypt, Argon2와 같이 의도적으로 느리고 메모리 집약적인 전용 비밀번호 해싱 함수를 사용하세요.
솔트 미사용: 솔트(해싱 전 각 비밀번호에 추가되는 랜덤 값) 없이 비밀번호를 해싱하면, 동일한 비밀번호가 동일한 해시를 생성합니다. 미리 계산된 "레인보우 테이블"을 가진 공격자는 일반적인 비밀번호를 즉시 찾을 수 있습니다. 항상 사용자별로 고유하고 랜덤한 솔트를 추가하세요.
타이밍에 안전하지 않은 방식으로 해시 비교: 보안에 민감한 코드에서 ==로 해시를 비교하면 타이밍 사이드 채널을 통해 정보가 유출될 수 있습니다. 공격자는 비교에 걸리는 시간을 측정하여 해시를 한 글자씩 추론할 수 있습니다. Node.js의 crypto.timingSafeEqual()이나 Python의 hmac.compare_digest() 같은 상수 시간 비교 함수를 사용하세요.
해시 잘라내기: 일부 개발자는 공간을 절약하기 위해 해시를 잘라냅니다(예: SHA-256 해시의 처음 16자만 저장). 이는 충돌 저항성을 극적으로 감소시킵니다. 완전한 SHA-256 해시는 2^256개의 가능한 값을 가집니다; 16개의 16진수 문자로 잘라내면 2^64만 남습니다 — 현대 하드웨어가 무차별 대입할 수 있는 숫자입니다.
어떤 해시 함수를 사용해야 할까?
- 파일 무결성(비보안): SHA-256 또는 MD5도 괜찮습니다. 우발적인 손상을 확인하는 것이지, 악의적인 변조가 아닙니다.
- 비밀번호 저장: 이것들 중 아무것도 안 됩니다! bcrypt, scrypt 또는 Argon2를 사용하세요 — 의도적으로 느려서 무차별 대입 공격을 비실용적으로 만듭니다. 일반 해시 함수는 비밀번호 해싱에 너무 빠릅니다.
- 디지털 서명과 인증서: SHA-256 또는 SHA-512.
- HMAC(메시지 인증): SHA-256 또는 SHA-512.
- Git 스타일 콘텐츠 주소 지정: SHA-256(Git이 향하는 방향).
- 미래 대비: 수십 년간 지속되어야 하는 시스템을 구축하고 SHA-2가 손상될 경우를 대비한 백업 계획이 필요하다면, SHA-3를 고려하세요.
- 데이터 파이프라인의 체크섬: 파이프라인 단계 간 데이터 무결성 검증에 SHA-256. CRC32가 더 빠르지만 우발적 오류만 잡고 의도적 변조는 잡지 못합니다.
코드에서의 해시 함수: 실용 예제
좋아요, 이론은 충분합니다 — 실제로 코드를 작성해 봅시다. 솔직히 해싱을 이해하는 가장 좋은 방법은 그냥... 직접 해보는 것입니다. 여러분이 매일 사용하는 언어로 해시를 계산하는 방법을 알려드리겠습니다.
Node.js — 내장 crypto 모듈이 이것을 매우 간단하게 만들어줍니다:
그리고 멋진 부분은 — 파일 해싱도 거의 같다는 것입니다:
Python — Python의 hashlib도 마찬가지로 간단합니다. 사실 Python이 이 용도로 가장 깔끔한 API를 가지고 있다고 생각합니다:
Go — Go의 표준 라이브러리는 이것을 위해 믿을 수 없을 만큼 잘 설계되어 있습니다:
Java — 좀 더 장황하지만(왜냐하면... Java니까요), 잘 작동합니다:
파일 다운로드 검증: 이것은 해싱의 가장 실용적인 사용 중 하나입니다. Linux ISO를 다운로드했고 웹사이트에서 SHA-256 체크섬이 abc123...이어야 한다고 하는 경우, 검증 방법은 다음과 같습니다:
이게 기본적인 것처럼 보일 수 있지만, 이 단계를 건너뛰는 개발자가 얼마나 많은지 알면 놀랄 것입니다. 4GB 다운로드에서 한 바이트가 손상되면 오후 전체가 망가질 수 있습니다.
레인보우 테이블과 그것이 무서운 이유
좋아요, 이 부분은 제가 처음 배웠을 때 정말 충격적이었습니다. 누군가가 가능한 모든 비밀번호의 해시를 미리 계산한다고 상상해 보세요 — 8자까지의 모든 글자, 숫자, 기호 조합. 그 모든 해시-비밀번호 매핑을 거대한 조회 테이블에 저장합니다.
그것이 레인보우 테이블입니다. 그리고 정말 무섭습니다.
이유는 이렇습니다: 비밀번호를 일반 SHA-256 해시로(솔트 없이) 저장했다면, 데이터베이스를 획득한 공격자는 아무것도 "크래킹"할 필요가 없습니다. 레인보우 테이블에서 각 해시를 조회하기만 하면 됩니다. 바로 — 즉시 비밀번호 복구. 조회에는 마이크로초밖에 걸리지 않습니다.
이 테이블이 얼마나 클까요? 8자까지의 모든 영숫자 비밀번호를 커버하는 레인보우 테이블은 약 100-200GB가 될 수 있습니다. 많아 보이지만 단일 SSD에 들어갑니다. CrackStation 같은 사이트는 수십억 개의 미리 계산된 해시가 있는 테이블을 가지고 있으며, 일반적인 비밀번호 해시를 무료로 몇 초 만에 크래킹합니다.
이제 좋은 소식입니다: 솔팅은 레인보우 테이블을 완전히 무력화합니다. 솔트는 해싱 전에 비밀번호에 추가하는 랜덤 문자열일 뿐입니다:
무슨 일이 일어났는지 보이시나요? 같은 비밀번호("password123")가 다른 솔트 때문에 완전히 다른 해시를 생성합니다. 공격자는 가능한 모든 솔트에 대해 별도의 레인보우 테이블을 만들어야 하는데, 이는 계산적으로 불가능합니다.
모든 현대 비밀번호 해싱 라이브러리(bcrypt, Argon2, scrypt)는 솔팅을 자동으로 처리합니다. 자체 비밀번호 해싱을 만들고 싶은 유혹이 든다면 — 하지 마세요. 진심으로. bcrypt를 사용하고 삶을 계속하세요.
HMAC: 비밀을 사용한 해싱
HMAC는 해시 기반 메시지 인증 코드의 약자입니다. 네, 알아요, 겁나게 들리죠. 하지만 잠깐만요 — 실제로는 여러분이 아마 모르는 사이에 이미 사용해 본 꽤 간단한 개념입니다.
일반 해싱은 메시지를 받아 해시를 생성합니다. HMAC는 메시지와 비밀 키를 받아 해시를 생성합니다. 핵심적인 차이(말장난 의도함)는 비밀 키를 아는 사람만 HMAC를 생성하거나 검증할 수 있다는 것입니다. 두 가지를 한 번에 증명합니다: 메시지가 변조되지 않았고, 비밀을 아는 사람이 보낸 것입니다.
실제로 어디서 볼 수 있을까요? 웹훅 서명입니다. GitHub이나 Stripe가 서버에 웹훅을 보낼 때, 헤더에 HMAC-SHA256 서명을 포함합니다. 서버는 HMAC를 직접 계산하고 비교하여 웹훅이 실제로 GitHub에서 온 것인지(랜덤한 공격자가 위조한 것이 아닌지) 검증할 수 있습니다.
Node.js에서 GitHub 웹훅 서명을 검증하는 실용 예제입니다:
timingSafeEqual 호출을 주목하셨나요? 이것은 매우 중요합니다. 일반 === 비교는 첫 번째 불일치 문자를 찾는 즉시 false를 반환하므로, 공격자가 응답 시간을 측정하여 서명을 바이트 단위로 알아낼 수 있습니다. 타이밍 안전 비교는 불일치가 어디에서 발생하든 항상 같은 시간이 걸립니다.
해시 함수 성능 벤치마크
이해합니다 — 성능은 중요합니다. 특히 빌드 파이프라인에서 수백만 개의 파일을 해싱하거나 대량의 데이터를 처리할 때 말이죠. 주요 해시 함수들의 속도 비교입니다(최신 x86_64 하드웨어에서의 대략적인 벤치마크):
잠깐, 눈치채셨나요? BLAKE3는 암호학적으로 안전하면서 SHA-256보다 10배 빠릅니다. 오타가 아닙니다.
BLAKE3는 해싱 세계의 최신 트렌드이며, 그럴 만한 이유가 있습니다. BLAKE2 패밀리(NIST 경쟁에서 이미 SHA-3를 이겼던)를 기반으로 하지만 SIMD 병렬성과 멀티스레딩을 활용하도록 재설계되었습니다. memcpy 속도에 가깝게 데이터를 해싱할 수 있습니다.
왜 신경 써야 할까요? 빌드 도구들이 신경 씁니다. 아주 많이. Bazel, Buck, 다양한 콘텐츠 주소 지정 스토리지 시스템 같은 도구들은 놀라운 양의 시간을 파일 해싱에 소비합니다. SHA-256에서 BLAKE3로 전환하면 종속성 검사를 한 자릿수 배율로 가속할 수 있습니다. Rust 생태계는 BLAKE3를 적극적으로 채택하고 있으며, 점점 더 많은 곳에서 나타나고 있습니다.
그렇지만, 광범위한 호환성이나 FIPS 같은 표준 준수가 필요할 때는 SHA-256과 SHA-512가 여전히 올바른 선택입니다. 아직 모든 것이 BLAKE3를 지원하지는 않으며, 많은 사용 사례에서 해싱 속도가 병목이 아닙니다.
블록체인과 머클 트리: 대규모 해싱
여기서 정말 멋진 부분이 나옵니다. Git이 거대한 저장소에서 정확히 어떤 파일이 변경되었는지 어떻게 알 수 있는지 아시나요? 비트코인이 전체 블록체인을 다운로드하지 않고도 트랜잭션을 어떻게 검증할 수 있는지? 비밀은 머클 트리라는 데이터 구조입니다(1979년에 특허를 낸 Ralph Merkle의 이름을 따서 명명).
머클 트리는 기본적으로 해시의 트리입니다. 작동 방식은 이렇습니다 — 네 개의 데이터 블록이 있다고 상상해 보세요:
각 리프 노드는 데이터 블록의 해시입니다. 각 부모 노드는 두 자식을 연결한 것의 해시입니다. 루트 해시(때로는 "머클 루트"라고 함)는 트리의 모든 데이터를 대표하는 단일 해시입니다.
여기 정말 우아한 부분이 있습니다: Data C의 한 비트만 변경되어도 Hash(C)가 변경되고, 이는 Hash(CD)가 변경되고, 이는 Root Hash가 변경됨을 의미합니다. 루트만 확인하면 변조를 즉시 감지할 수 있습니다.
하지만 더 좋아집니다. Data A, B, D를 공개하지 않고 Data C가 트리의 일부임을 증명하고 싶다고 해봅시다. Data C, Hash(D), Hash(AB)만 제공하면 됩니다. 검증자는 루트까지의 경로를 재구성하고 일치하는지 확인할 수 있습니다. 이것을 "머클 증명"이라고 하며, 놀랍도록 효율적입니다 — 백만 개의 리프가 있는 트리에서 증명은 약 20개의 해시 길이에 불과합니다(log2 of 1,000,000).
실제로 어디에 사용될까요?
- Git: 전체 저장소가 머클 트리입니다. 커밋은 트리를 가리키고, 트리는 블롭을 가리키며, 모든 것이 SHA-1 해시로 식별됩니다. Git이 무언가 변경되었는지 즉시 알 수 있는 이유입니다.
- 비트코인: 각 블록에는 모든 트랜잭션의 머클 루트가 포함됩니다. 라이트 클라이언트(모바일 지갑 등)는 전체 블록을 다운로드하지 않고 머클 증명을 사용하여 특정 트랜잭션을 검증할 수 있습니다.
- IPFS: InterPlanetary File System은 파일을 청크로 나누고, 머클 DAG(비순환 유향 그래프)를 구축하고, 루트 해시를 파일의 콘텐츠 식별자(CID)로 사용합니다.
- Certificate Transparency: Google의 Certificate Transparency 로그는 머클 트리를 사용하여 누구나 인증서가 기록되었는지(또는 안 되었는지) 효율적으로 검증할 수 있게 합니다.
미래: 포스트 양자 해시 함수
양자 컴퓨터가 모든 암호화를 깨뜨릴 것이라는 이야기를 들어보셨을 겁니다. 맞습니다, 부분적으로는요 — RSA, ECC, Diffie-Hellman은 대규모 양자 컴퓨터가 도래하면 모두 끝입니다. Shor의 알고리즘은 큰 수를 효율적으로 인수분해하고 이산 로그를 계산할 수 있으며, 이것이 그 시스템들의 기반입니다.
하지만 놀랍게도 좋은 소식이 있습니다: 해시 함수는 실제로 양자 컴퓨터에 대해 꽤 안전합니다. 해시 함수에 대한 주요 양자 위협은 Grover의 알고리즘으로, 비구조화된 공간을 2차적으로 더 빠르게 검색할 수 있습니다. 실제로 이는 보안 비트를 절반으로 줄인다는 것을 의미합니다 — SHA-256은 양자 공격에 대해 2^256에서 2^128 강도로 줄어듭니다.
2^128은 여전히 절대적으로 거대합니다. 이것은 대략 관측 가능한 우주의 원자 수의 제곱입니다. 양자 컴퓨터든 아니든 아무도 이것을 무차별 대입할 수 없습니다.
따라서 NIST가 포스트 양자 암호화 표준을 적극적으로 작업하고 있고(2024년에 여러 개를 확정), 긴급성은 주로 공개 키 암호화와 서명에 있습니다 — 해시 함수가 아닙니다. 오늘 SHA-256을 사용하고 있다면, 양자 컴퓨터가 그것을 쓸모없게 만들지 않을 것이라는 것을 알고 편히 잠들 수 있습니다.
정말 편집증적이라면(그리고 암호학에서 편집증은 미덕입니다), SHA-512나 SHA3-256으로 업그레이드하면 추가 안전 마진을 얻을 수 있습니다. SPHINCS+와 같은 일부 포스트 양자 서명 체계는 전적으로 해시 함수 위에 구축되어 있으며, 이는 양자 저항성에 대한 멋진 신뢰의 표입니다.
해시 충돌: 생일 공격 설명
컴퓨터 과학에서 가장 직관에 반하는 것 중 하나에 대해 이야기해 봅시다: 생일 공격. 생일 역설에서 이름을 따왔으며, 해시 함수가 직관적으로 예상하는 것보다 더 커야 하는 이유입니다.
생일 역설: 단 23명이 있는 방에서 그 중 두 명이 같은 생일을 가질 확률이 50%입니다. 특정 생일이 아니라 — 아무 일치하는 쌍이요. 70명이면 확률이 99.9%로 뛰어오릅니다. 대부분의 사람들은 183명(365의 절반) 정도가 필요할 것으로 추측하지만, 실제 숫자는 훨씬 낮습니다. 특정 충돌이 아니라 아무 충돌이나 찾기 때문입니다.
정확히 같은 수학이 해시 함수에 적용됩니다. 해시 함수가 N개의 가능한 출력을 생성한다면, 충돌을 찾기 위해 N개의 해시를 계산할 필요가 없습니다 — 대략 N의 제곱근만 필요합니다.
SHA-256같은 256비트 해시의 경우, 2^256개의 가능한 출력이 있습니다. 충돌을 찾으려면 약 2^128번의 연산이 필요합니다(2^256의 제곱근). 이것은 여전히 불가능하게 큰 숫자입니다 — 하지만 64비트 해시를 사용하고 끝낼 수 없는 이유입니다.
이것이 바로 MD5(128비트)가 무너진 이유입니다. 충돌 저항성이 처음부터 2^64에 불과했고, 알고리즘의 구조적 약점이 그것을 더 낮췄습니다. 연구자들은 결국 일반 노트북에서 몇 초 만에 충돌을 찾았습니다.
실용적인 결론? 보안 관련 모든 것에 최소 256비트 해시 함수를 항상 사용하세요. SHA-256, SHA3-256, BLAKE3 모두 훌륭한 선택입니다. 누군가 보안 목적으로 64비트 또는 128비트 해시를 사용하자고 제안한다면, 이제 그것이 끔찍한 아이디어인 이유를 정확히 아시겠죠.
직접 시도해 보세요
데이터의 해시 값이 궁금하신가요? MD5 해시 생성기, SHA-256 해시 생성기 또는 SHA-512 해시 생성기를 사용해 보세요. 텍스트를 붙여넣고 아주 작은 변경으로도 해시가 완전히 달라지는 것을 확인하세요 — 이 알고리즘들이 어떻게 동작하는지 직관을 쌓는 가장 좋은 방법입니다.