Skip to content
블로그로 돌아가기
튜토리얼

MD5 vs SHA-256: 개발자를 위한 온라인 해시 알고리즘 비교

MD5, SHA-1, SHA-256, SHA-512를 보안·속도·출력 크기 관점에서 비교하고, 체크섬과 비밀번호 저장에 어떤 해시를 골라야 하는지 정리한 온라인 가이드입니다.

12분 소요

MD5 vs SHA-256, 어떤 해시 알고리즘을 써야 할까?

해싱은 컴퓨팅의 기본 연산이지만 잘못된 알고리즘을 고르면 충돌 공격, 데이터 무결성 훼손, 불필요한 성능 오버헤드에 노출됩니다. 아래에서 가장 널리 쓰이는 네 가지 해시 알고리즘을 비교하고 선택 기준을 정리합니다.

해시 함수란?

암호학적 해시 함수는 임의의 입력 데이터를 받아 고정된 크기의 출력(‘다이제스트’ 또는 ‘해시’)을 만듭니다. 좋은 해시 함수는 다음 세 가지 속성을 갖춰야 합니다.

  1. 결정론적: 같은 입력은 언제나 같은 출력을 냅니다.
  2. 일방향성: 해시 값에서 원본 입력을 복원할 수 없습니다.
  3. 충돌 저항성: 동일한 해시를 내는 서로 다른 두 입력을 찾는 것이 계산적으로 불가능합니다.

세 번째 속성이 무너지면 해당 알고리즘은 “암호학적으로 깨진(cryptographically broken)” 상태가 됩니다. MD5와 SHA-1에서 실제로 벌어진 일입니다.

알고리즘 한눈에 비교

항목MD5SHA-1SHA-256SHA-512
출력 크기128 비트 (16진수 32자)160 비트 (16진수 40자)256 비트 (16진수 64자)512 비트 (16진수 128자)
블록 크기512 비트512 비트512 비트1024 비트
공개 연도1991년1995년2001년2001년
설계자Ron RivestNSA / NISTNSA / NISTNSA / NIST
충돌 저항성깨짐 (2004년)깨짐 (2017년)안전안전
상대 속도가장 빠름빠름보통보통 (64비트에서 더 빠름)
NIST 지위권장 중단권장 중단권장권장

MD5: 빠르지만 깨진 알고리즘

MD5(Message-Digest Algorithm 5)는 1991년 Ronald Rivest(론 리베스트)가 설계했으며, 1990~2000년대 초 체크섬의 사실상 표준으로 쓰였습니다. 128 비트 해시를 16진수 32자로 출력합니다.

MD5가 깨진 이유

2004년 Xiaoyun Wang이 MD5에 대한 실용적인 충돌 공격을 시연했습니다. 2008년에는 연구자들이 MD5 충돌로 위조 SSL 인증서를 만들어 내면서 이 공격이 이론에 머물지 않는다는 사실이 증명되었습니다. 오늘날 MD5 충돌은 일반 소비자용 하드웨어에서 몇 초면 생성할 수 있습니다.

// MD5 해시 생성 (보안 용도가 아닌 경우에만 사용)
// Web Crypto API는 MD5를 지원하지 않으므로 라이브러리를 사용합니다
import { md5 } from 'hash-wasm';

const hash = await md5('Hello, World!');
console.log(hash);
// → 'bea8252ff4e80f41719ea13cdf007273' (16진수 32자)

MD5를 아직 써도 괜찮은 경우

암호학적으로 깨졌지만 보안과 무관한 용도에서는 여전히 유용합니다.

  • 파일 중복 제거: 스토리지 시스템에서 동일한 파일을 찾아내기
  • 캐시 키: 캐시 조회용으로 짧고 결정론적인 키를 생성하기
  • 데이터 무결성 체크섬: 데이터가 우연히 손상되지 않았는지 빠르게 확인하기(의도적 조작 탐지 용도는 아님)
  • 레거시 호환: MD5를 요구하는 구형 시스템과 상호 운용하기

요약하자면 MD5는 우연한 손상은 잡아내지만 의도적인 조작은 막지 못합니다.

SHA-1: 권장 중단되었지만 여전히 남아 있는

SHA-1(Secure Hash Algorithm 1)은 NSA가 설계하고 1995년 NIST가 발표했습니다. 160 비트 해시를 16진수 40자로 출력합니다.

2017년 Google과 CWI Amsterdam은 최초의 실용적인 SHA-1 충돌(“SHAttered” 공격)을 시연하며 같은 SHA-1 해시를 갖는 서로 다른 두 PDF 파일을 만들어 냈습니다. 주요 브라우저와 인증 기관은 2016년부터 이미 SHA-1 인증서를 거부하고 있었습니다.

SHA-1은 이를 명시적으로 요구하는 시스템과의 호환 목적으로만 쓰세요. Git은 커밋 해시에 SHA-1을 쓰지만 SHA-256으로 전환 중입니다. 새 프로젝트는 SHA-256 이상을 선택하세요.

SHA-256: 현재의 표준

SHA-256은 SHA-2 계열의 하나로, NSA가 설계하고 2001년 NIST가 발표했습니다. 256 비트 해시를 16진수 64자로 출력하며, 2026년 현재 거의 모든 해싱 용도에 권장되는 알고리즘입니다.

// Web Crypto API로 SHA-256 해시 생성 (브라우저 내장)
async function sha256(text) {
  const data = new TextEncoder().encode(text);
  const hash = await crypto.subtle.digest('SHA-256', data);
  return Array.from(new Uint8Array(hash))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
}

const hash = await sha256('Hello, World!');
console.log(hash);
// → 'dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f'

SHA-256이 기본 선택인 이유

  • 알려진 공격 없음: 2026년 현재 SHA-256에 대한 실용적인 충돌/역상 공격은 존재하지 않습니다
  • 브라우저 내장: 모든 최신 브라우저가 Web Crypto API로 지원하므로 별도 라이브러리가 필요 없습니다
  • 업계 표준: TLS 인증서, Bitcoin, 패키지 매니저(npm, pip), Docker 이미지 다이제스트, 대부분의 무결성 검증 시스템이 SHA-256을 사용합니다
  • NIST 승인: 보안이 중요한 모든 애플리케이션에 권장됩니다

SHA-512: 더 강한 여유가 필요할 때

SHA-512는 512 비트 해시를 16진수 128자로 출력합니다. 블록 크기가 1024 비트(SHA-256은 512 비트)여서 64비트 프로세서에서는 사이클당 더 많은 데이터를 처리해 SHA-256보다 빠릅니다.

# Python: SHA-512도 SHA-256만큼 쉽습니다
import hashlib

hash_256 = hashlib.sha256(b'Hello, World!').hexdigest()
hash_512 = hashlib.sha512(b'Hello, World!').hexdigest()

print(f"SHA-256: {hash_256}")  # 64자
print(f"SHA-512: {hash_512}")  # 128자

SHA-512는 다음과 같은 경우에 사용합니다.

  • 더 큰 보안 여유가 필요할 때 (SHA-256의 128 비트 충돌 저항성 대비 256 비트)
  • 64비트 플랫폼에서 성능이 중요할 때 (x86-64에서 SHA-512가 SHA-256보다 1.5배 빠른 경우도 있음)
  • 프로토콜이나 규격이 요구할 때 (일부 인증서 체계, 특정 컴플라이언스 요구 사항)

대부분은 SHA-256으로 충분합니다. SHA-512는 해시 길이가 두 배로 늘어나 저장 공간과 대역폭을 그만큼 더 소모하지만, 일반 용도에서는 실질적인 보안 이점이 없습니다.

의사 결정 프레임워크: 어떤 해시를 쓸 것인가

파일 무결성과 체크섬

SHA-256을 쓰세요. 다운로드 검증, 파일 내용 비교, 데이터 무결성 확인의 표준 알고리즘입니다. 기존 MD5 시스템 교체에도 SHA-256이 가장 자연스러운 드롭인 업그레이드입니다.

# 다운로드 파일의 무결성 검증
sha256sum downloaded-file.tar.gz
# 출력값을 공개된 해시와 비교

비밀번호 저장

MD5도, SHA-256도 그대로 쓰지 마세요. 범용 해시 함수는 비밀번호 해싱에 너무 빠릅니다. 공격자가 초당 수십억 번의 추측을 시도할 수 있습니다. 대신 비밀번호 해싱 전용 알고리즘을 쓰세요.

알고리즘상태비고
Argon2id권장2015년 Password Hashing Competition 우승자, 메모리 하드
bcrypt양호폭넓은 지원, 내장 salt, 조절 가능한 작업 계수
scrypt양호메모리 하드, 일부 암호화폐 시스템에서 사용
PBKDF2허용 가능NIST 승인이지만 메모리 하드는 아님, ≥ 600,000회 반복 권장
SHA-256부적합너무 빠르고 내장 salt가 없으며, GPU 공격에 취약
MD5위험깨졌고 너무 빠름, 손쉽게 복원됨
// 잘못된 예: 비밀번호를 SHA-256으로 해싱하지 말 것
const hash = await sha256(password); // 초당 수십억 회로 돌파 가능

// 올바른 예: bcrypt 사용 (Node.js)
import bcrypt from 'bcrypt';
const hash = await bcrypt.hash(password, 12); // 12 rounds ≈ 250ms
const isValid = await bcrypt.compare(input, hash);

HMAC과 메시지 인증

HMAC과 SHA-256을 조합합니다. HMAC(Hash-based Message Authentication Code)은 해시 함수와 비밀 키를 결합해 무결성과 진위성을 동시에 검증합니다.

// 웹훅 서명 검증용 HMAC-SHA256
async function verifyWebhook(payload, signature, secret) {
  const key = await crypto.subtle.importKey(
    'raw', new TextEncoder().encode(secret),
    { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']
  );
  const sig = Uint8Array.from(atob(signature), c => c.charCodeAt(0));
  return crypto.subtle.verify('HMAC', key, sig, new TextEncoder().encode(payload));
}

콘텐츠 주소 지정 스토리지

SHA-256을 쓰세요. Git, Docker, IPFS는 콘텐츠의 해시를 주소로 삼는 콘텐츠 주소 지정(content-addressable) 스토리지를 쓰며, SHA-256은 수십억 개의 객체 사이에서도 유일성을 보장할 충돌 저항성을 갖추고 있습니다.

성능 벤치마크

최신 x86-64 프로세서에서의 상대적 해싱 속도(높을수록 빠름)는 다음과 같습니다.

알고리즘처리량 (MB/s)상대 속도
MD5~3,2001.0배 (기준)
SHA-1~2,4000.75배
SHA-256~1,5000.47배
SHA-512~2,1000.66배

참고: SHA-512는 내부 상태가 더 넓어 64비트 프로세서에서 SHA-256보다 빠릅니다. 32비트 시스템에서는 반대입니다. 대부분의 용도에서는 속도 차이가 무시할 수준입니다. 1 MB 파일은 어느 알고리즘으로도 1 ms 안에 해싱됩니다.

흔히 저지르는 실수

1. 보안 용도로 MD5를 사용

MD5 충돌은 손쉽게 만들 수 있습니다. 디지털 서명, 인증서 검증, 공격자가 악의적 입력을 설계할 수 있는 상황에서 MD5를 쓰지 마세요.

2. 비밀번호를 SHA-256으로 해싱

SHA-256은 비밀번호 해시가 아닙니다. 너무 빠르고, 내장 salt가 없으며, 레인보우 테이블(Rainbow Table)과 GPU 가속 무차별 대입에 취약합니다. Argon2id나 bcrypt를 쓰세요. 무차별 대입 저항성의 수학적 배경은 비밀번호 엔트로피 가이드를 참고하세요.

3. 해시 길이를 보안 강도와 동일시

512 비트 해시가 256 비트 해시보다 자동으로 “더 안전한” 것은 아닙니다. 충돌 저항성 관점에서 SHA-256의 128 비트 여유는 이미 무차별 대입 한계를 한참 벗어납니다. 실제 요구 사항에 맞춰 고르고, 단순한 해시 길이로 판단하지 마세요.

4. 직접 조합한 해시 구성

SHA256(MD5(data))MD5(data + salt) 같은 패턴은 깨진 알고리즘을 고쳐 주지 않습니다. 검증된 단일 알고리즘(SHA-256)이나 올바른 구성(HMAC)을 쓰세요.

직접 시도해 보기

Hash Generator에서 MD5, SHA-1, SHA-256, SHA-512 해시를 즉시 생성하고 비교할 수 있습니다. 텍스트를 붙여 넣거나 파일을 올리면 네 가지 다이제스트를 한 화면에서 나란히 확인할 수 있고, 모든 처리는 브라우저 안에서 이뤄지므로 데이터는 기기를 벗어나지 않습니다.

인증, 입력 유효성 검사, 보안 헤더 등 더 넓은 웹 보안 주제는 웹 보안 모범 사례 가이드에서 다룹니다. 인코딩·해싱·데이터 변환 전반은 개발자 필수 도구 가이드도 함께 참고하세요.

자주 묻는 질문

MD5는 체크섬 용도로 여전히 안전한가요?

조건부로 그렇습니다. MD5는 파일이 우연히 손상됐는지 감지하는 용도로는 안전합니다. 다운로드 중 파일이 훼손되면 MD5 해시도 거의 확실히 달라지기 때문입니다. 다만 공격자가 같은 MD5 해시를 갖는 변조 파일을 만들 수 있으므로 의도적 조작에는 안전하지 않습니다. 소프트웨어 배포처럼 악의적 공격자를 고려해야 하는 무결성 검증에는 SHA-256을 쓰세요.

SHA-256은 MD5보다 얼마나 느린가요?

순수 처리량 기준으로 SHA-256은 MD5보다 약 2배 느립니다. 최신 하드웨어에서 MD5는 약 3,200 MB/s, SHA-256은 약 1,500 MB/s입니다. 대부분의 애플리케이션에서는 이 차이가 무시할 수준이고, 100 MB 파일도 SHA-256으로 약 70 ms면 끝납니다. 성능 격차가 실제 문제가 되는 건 네트워크 패킷 검사나 대규모 스토리지 중복 제거처럼 매우 높은 처리량이 필요한 경우뿐입니다.

제 애플리케이션에 SHA-256과 SHA-512 중 어느 쪽을 써야 하나요?

대부분 SHA-256을 쓰세요. 128 비트 충돌 저항성은 이미 무차별 대입 한계를 한참 넘어서는 수준입니다. SHA-512는 다음 조건에서 고르세요. (a) 플랫폼이 64비트이며 최대 처리량이 필요할 때, (b) 규격이나 규정 준수가 명시적으로 요구할 때, (c) 장기 데이터 무결성을 위해 더 큰 보안 여유가 필요할 때. SHA-512의 추가 해시 길이는 저장 공간을 두 배로 늘리며 대체로 불필요합니다.

SHA-256은 복호화하거나 역산할 수 있나요?

아닙니다. SHA-256은 일방향 함수여서 역산할 수 없습니다. 2026년 현재 SHA-256에 대한 실용적인 역상 공격이나 충돌 공격은 존재하지 않습니다. 알려진 최선의 충돌 공격조차 2^128회의 연산이 필요한데, 이는 현재와 가까운 미래의 기술로 계산 불가능합니다. SHA-256은 NIST 승인을 받았으며 TLS, Bitcoin, 연방 정부 시스템 등 핵심 인프라에서 쓰입니다.

MD5가 깨졌는데도 아직 쓰는 시스템이 있는 이유는 무엇인가요?

가장 큰 이유는 레거시 호환입니다. 많은 기존 시스템과 프로토콜, 파일 포맷이 MD5 취약점이 드러나기 전에 MD5를 중심으로 설계됐고, 거기서 벗어나려면 모든 구성 요소를 함께 바꿔야 합니다. 캐시 키나 중복 제거처럼 보안과 무관한 용도에서는 충돌 공격이 위협 모델 밖이어서 MD5의 빠른 속도와 짧은 출력이 실용적인 선택으로 남기도 합니다.