T도구모음

해시 생성기 (MD5/SHA)

텍스트의 MD5, SHA-1, SHA-256 해시 값을 생성합니다.

해시 생성기 — 체크섬에서 HMAC까지, 풀스택 개발자의 암호학 도구상자

프로덕션 환경에서 파일 업로드 중복 감지, ETag 생성, 비밀번호 마이그레이션, 캐시 무효화 키 생성 같은 작업을 하다 보면 하루에도 수십 번 해시 함수와 씨름하게 됩니다. 해시(Hash)는 임의 길이 입력을 고정 길이 출력으로 매핑하는 단방향 함수로, 같은 입력에는 항상 같은 출력이 나오는 결정성(determinism), 서로 다른 입력이 같은 출력을 만들기 극히 어려운 충돌 저항성(collision resistance), 출력에서 입력을 역산할 수 없는 일방향성(pre-image resistance) 세 가지 속성을 만족해야 합니다. 이 도구는 브라우저의 Web Crypto API(SubtleCrypto.digest)를 활용해 MD5, SHA-1, SHA-256을 로컬에서 즉시 계산하므로, 입력 데이터가 서버로 전송되지 않아 안심하고 사용할 수 있습니다.

알고리즘별 표준과 내부 구조

SHA-2 계열(SHA-256, SHA-384, SHA-512)은 NIST FIPS 180-4에 정의된 Merkle-Damgard 구조 기반입니다. SHA-256은 메시지를 512비트 블록으로 분할하고, 각 블록에 대해 64라운드의 압축 함수(Ch, Maj, Sigma 연산)를 적용해 최종 256비트 다이제스트를 생성합니다.SHA-3(Keccak)은 FIPS 202에 정의된 sponge 구조로, SHA-2와 수학적 기반이 완전히 다르므로 SHA-2에 취약점이 발견되더라도 대체 수단으로 활용 가능합니다.MD5(RFC 1321)와 SHA-1(RFC 3174)은 이미 실전 충돌이 증명되었으며, 특히 2017년 Google의 SHAttered 프로젝트에서 SHA-1 충돌 PDF가 공개된 이후 서명이나 인증 용도로는 절대 사용해서는 안 됩니다.

알고리즘출력 길이표준 문서보안 상태
MD5128bit (32자)RFC 1321깨짐 — 보안용 금지
SHA-1160bit (40자)RFC 3174깨짐 — Deprecated
SHA-256256bit (64자)FIPS 180-4안전 (권장)
SHA-512512bit (128자)FIPS 180-4안전
SHA-3 (Keccak)224~512bitFIPS 202안전 (차세대)
bcrypt / Argon2가변RFC 9106비밀번호 전용

구체 예시 — SHA-256 다이제스트 검증

SHA-256("hello")의 16진 다이제스트는 아래와 같습니다. 같은 입력이라면 언어·플랫폼에 관계없이 동일한 값이 나와야 하므로, 이 값을 리트머스 테스트로 사용하면 라이브러리 구현이 올바른지 빠르게 판별할 수 있습니다.

SHA-256("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
MD5("hello")     = 5d41402abc4b2a76b9719d911017c592
SHA-1("hello")   = aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d

// Node.js에서 확인
const crypto = require('crypto');
crypto.createHash('sha256').update('hello').digest('hex');
// → "2cf24dba5fb0a30e..."

// 브라우저 Web Crypto API
const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode('hello'));
Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2,'0')).join('');

실무 활용 시나리오 5가지

  • 파일 무결성 검증 — ISO 이미지 다운로드 시 제공되는 SHA-256 체크섬으로 변조 여부를 확인합니다. sha256sum ubuntu.iso 한 줄이면 끝.
  • Git 객체 식별 — Git은 모든 blob, tree, commit 객체를 SHA-1(최근 SHA-256 전환 실험 중)으로 어드레싱합니다. 커밋 해시가 바로 이것.
  • CDN 캐시 무효화 — 정적 파일 URL에 ?v=<sha256 앞 8자>를 붙여 immutable 캐싱 전략을 구현합니다.
  • HMAC 서명 — JWT의 HS256 알고리즘은 SHA-256 기반 HMAC으로 토큰 위변조를 검증합니다. 키 없이 서명을 재현할 수 없는 원리.
  • 업로드 중복 감지 — S3 업로드 전 SHA-256 다이제스트가 동일하면 바이트 비교 없이도 중복으로 판단해 스토리지 비용을 절감합니다.

실전 디버깅 — 한 번은 당해보는 인코딩 함정

SHA-256을 Node.js와 브라우저에서 동시에 사용했을 때 값이 달라서 반나절을 날린 경험이 있습니다. 원인은 문자 인코딩: 한글 입력을 UTF-16 바이트로 해시한 쪽과 UTF-8로 해시한 쪽의 결과가 당연히 다릅니다. 해결책은 간단합니다 — 반드시 new TextEncoder().encode(str)로 UTF-8 바이트 배열을 먼저 만들고, 그 바이트 배열을 해시 함수에 전달하는 것입니다. 또 하나 흔한 사고: 대용량 파일을 한 번에 digest()에 넣으려다 OOM(Out of Memory)으로 프로세스가 죽는 경우. Node.js에서는 createHash().update(chunk)를 스트림으로 파이프하고, 브라우저에서는 ReadableStream과 TransformStream을 조합해 청크 단위로 처리해야 합니다.

보안 경고 — 비밀번호를 생 해시로 저장하면 안 되는 이유

가장 흔한 실수가 sha256(password)를 그대로 DB에 저장하는 것입니다. SHA-256은 너무 빠른 해시이기 때문에 NVIDIA RTX 4090 한 장으로 초당 약 100억 번 이상의 brute force가 가능합니다. 비밀번호 저장에는 반드시 bcrypt(cost factor 12 이상), scrypt, 또는 Argon2id(RFC 9106, OWASP 최우선 권장)처럼 의도적으로 느린 KDF(Key Derivation Function)를 사용하고, 각 비밀번호마다 고유한 salt를 붙여야 레인보우 테이블 공격을 차단할 수 있습니다. NIST SP 800-131A는 MD5와 SHA-1을 이미 deprecated 처리했으므로, 신규 시스템에서 사용하면 보안 감사에서 즉시 지적받습니다.

관련 도구

강력한 salt 원재료가 필요하면 비밀번호 생성기의 CSPRNG을 활용하고, 16진 해시 형식 검증 패턴(^[a-f0-9]{64}$)은 정규식 테스터에서 즉시 실험해 볼 수 있습니다. API 토큰 변경 전후를 비교할 때는 텍스트 차이 비교도 같이 쓰면 편리합니다.

참고 자료

  • NIST FIPS 180-4 — Secure Hash Standard (SHA-2 계열 정의)
  • NIST FIPS 202 — SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
  • RFC 9106 — Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work
  • OWASP Password Storage Cheat Sheet — bcrypt, scrypt, Argon2 비교
  • MDN Web Docs — SubtleCrypto.digest() API 레퍼런스

자주 묻는 질문

관련 도구