왜 브라우저 표준 해시 API는 MD5를 지원하지 않는가
브라우저 콘솔에서 crypto.subtle.digest('MD5', ...)를 직접 호출해 보면 즉시 NotSupportedError 예외가 발생합니다. SHA-256이나 SHA-1은 되는데 MD5만 안 되는 이유는 구현 실수가 아니라, 브라우저 표준 자체가 애초에 MD5를 지원 목록에서 뺐기 때문입니다. 왜 이런 선택을 했는지, 그리고 그럼에도 MD5 해시가 필요한 상황은 실제로 어떻게 처리하는지 살펴봅니다.
1. MD5가 표준에서 배제된 근본 이유: 이미 죽은 암호였다
MD5는 1992년 발표된 해시 함수로, 1996년 초기 취약점이 학계에서 지적되기 시작했고 2004~2005년 왕샤오윈(Wang Xiaoyun) 등의 연구로 실제 충돌(서로 다른 두 입력이 같은 해시값을 만드는 상황)을 인위적으로 만들어내는 공격이 성공했습니다. 이후 MD5는 보안 무결성 검증이나 전자서명 용도로는 사실상 폐기된 알고리즘으로 취급됩니다. Web Crypto API는 2013~2017년 사이 W3C에서 표준화됐는데, 이 시점에 이미 MD5는 신뢰할 수 없는 알고리즘으로 결론이 난 상태였기 때문에 새 표준에 아예 포함시키지 않았습니다.
2. SubtleCrypto 스펙이 정의한 지원 알고리즘
crypto.subtle.digest()의 W3C 명세는 다이제스트 알고리즘으로 SHA-1, SHA-256, SHA-384, SHA-512 네 가지만 정의합니다. SHA-1조차 충돌 공격(2017년 구글의 SHAttered 연구)이 실증돼 보안 용도로는 권장되지 않지만, 하위 호환을 위해 스펙에는 남아 있습니다. MD5는 SHA-1보다 먼저, 더 심각하게 깨진 알고리즘이라 아예 논의 대상조차 되지 않았습니다.
await crypto.subtle.digest(algo, data) 한 줄로 모든 해시를 계산합니다. algo 값으로 'SHA-256'을 넘기면 정상 동작하지만, 'MD5'를 넘기면 브라우저가 즉시 예외를 던지므로 이 도구는 MD5를 아예 지원 알고리즘 목록에서 제외하고 SHA-1/256/384/512 4종만 제공합니다.
3. 그래서 MD5가 필요할 땐 어떻게 하는가: 순수 JS 구현
Web Crypto API로 계산할 수 없다고 해서 브라우저에서 MD5 계산 자체가 불가능한 것은 아닙니다. 알고리즘을 JavaScript 코드로 직접 구현하면 됩니다. 실제로 같은 사이트의 해시 생성기는 SHA 계열은 crypto.subtle.digest를 쓰면서도, MD5만큼은 md5cmn·md5ff·md5gg 같은 내부 함수로 구성된 순수 JS MD5 알고리즘을 직접 구현해서 계산합니다. 브라우저 표준 API가 못 하는 부분을 애플리케이션 레벨 라이브러리로 메꾸는 전형적인 패턴입니다.
4. 표준 API 방식과 순수 JS 구현 방식의 차이
| 구분 | Web Crypto API | 순수 JS 구현 |
|---|---|---|
| 지원 알고리즘 | SHA-1/256/384/512만 | MD5 포함 임의 알고리즘 가능 |
| 실행 속도 | 브라우저 네이티브 코드, 빠름 | JS 인터프리터 실행, 상대적으로 느림 |
| 구현 신뢰도 | 브라우저 벤더가 검증 | 라이브러리 코드 품질에 의존 |
| 이 사이트 예시 | hash-checker.html (SHA 전용) | hash-generator.html (MD5 자체 구현 포함) |
5. MD5를 여전히 써도 되는 용도, 안 되는 용도
- 써도 되는 경우: 파일 중복 감지, 캐시 무효화 키, 비보안 목적의 체크섬처럼 "고의적 위조 공격"을 가정하지 않는 상황.
- 쓰면 안 되는 경우: 비밀번호 저장, 디지털 서명, 파일 무결성 보증처럼 공격자가 의도적으로 원본과 다른 데이터로 같은 해시를 만들 수 있는 상황(충돌 공격) 자체가 문제가 되는 보안 용도.
보안이 필요한 경우 SHA-256 생성기를, 비밀번호 저장이라면 해시가 아닌 bcrypt 생성기 같은 전용 키 스트레칭 알고리즘을 사용해야 합니다.
자주 묻는 질문
Q. crypto.subtle.digest('MD5', data)를 호출하면 정확히 무슨 에러가 나나요?
브라우저마다 문구는 다르지만 대체로 "Algorithm: Unrecognized name" 또는 NotSupportedError 계열의 예외가 발생합니다. 스펙에 정의되지 않은 알고리즘 이름을 넘겼기 때문입니다.
Q. Node.js에서는 MD5를 계산할 수 있나요?
네. Node.js의 crypto 모듈은 OpenSSL 기반이라 브라우저 표준(SubtleCrypto)과 별개로 MD5를 포함한 훨씬 다양한 알고리즘을 지원합니다. 브라우저에서 제약이 있는 것은 SubtleCrypto라는 웹 표준 스펙 자체의 제한 때문입니다.
Q. SHA-1도 언젠가 표준에서 빠지나요?
가능성이 있습니다. 이미 보안 용도로는 권장되지 않지만, 레거시 시스템과의 호환을 위해 현재 스펙에는 남아 있습니다. MD5처럼 완전히 배제되기까지는 시간이 걸릴 수 있습니다.