MD5 해시 생성기
임의의 텍스트에서 MD5 해시 생성
입력 텍스트
MD5 해시
MD5 해시가 여기에 표시됩니다…
MD5 해싱이란 무엇입니까?
MD5(Message-Digest Algorithm 5)는 입력의 크기에 관계없이 모든 입력에서 고정된 128비트(16바이트) 다이제스트를 생성하는 암호화 해시 함수입니다. 1992년 Ronald Rivest가 RFC 1321로 발표한 MD5는 MD4의 더 빠른 후속 알고리즘으로 설계되어 인터넷에서 가장 널리 사용되는 해시 함수 중 하나가 되었습니다. 이 알고리즘은 입력을 512비트 블록으로 처리하며, 라운드당 다른 비선형 함수를 사용하는 4라운드 각 16개 연산을 통해 32자 16진수 지문을 생성합니다.
해시 함수는 단방향 변환입니다. 입력이 주어지면 해시를 즉시 계산할 수 있지만, 해시만으로는 원래 입력을 복구할 수 없습니다. 입력의 단 1비트 변경만으로도 완전히 다른 다이제스트가 생성됩니다. 이를 눈사태 효과(avalanche effect)라고 합니다. MD5는 무한한 입력 공간을 고정된 128비트 출력 공간으로 매핑하므로, 서로 다른 두 입력이 동일한 해시를 생성하는 충돌(collision)은 수학적으로 반드시 존재합니다. 그러나 안전한 해시 함수라면 충돌을 찾는 것이 계산상 불가능해야 합니다.
2004년부터 연구자들은 MD5에 대한 실용적인 충돌 공격을 입증했습니다. 이는 디지털 서명, 인증서, 또는 충돌 저항성이 필요한 모든 상황에서 더 이상 안전하지 않음을 의미합니다. 그러나 MD5는 비보안 목적으로 여전히 널리 사용됩니다. 다운로드 후 파일 무결성 검증, 캐시 키 생성, 콘텐츠 중복 제거, 문자열에서 결정론적 식별자 생성 등에 활용됩니다. 이러한 용도에서는 알고리즘의 속도와 광범위한 라이브러리 지원이 실용적인 선택이 됩니다. 2008년 Marc Stevens와 동료들은 선택 접두사 충돌 공격(chosen-prefix collision attack)을 발표했습니다. 공격자가 동일한 다이제스트를 공유하는 임의의 접두사를 가진 두 문서를 만들 수 있음을 의미합니다. 이 기법은 2008년 Chaos Communication Congress에서 악성 인증 기관(CA) 인증서를 구성하는 방식으로 시연되었습니다. 2012년 Flame 악성 코드는 선택 접두사 충돌을 악용하여 Microsoft 코드 서명 인증서를 위조했고, 악성 코드가 합법적인 Windows Update 패키지로 위장할 수 있었습니다. 이러한 실제 공격 사례들은 이 알고리즘이 입력에 영향을 줄 수 있는 공격자가 있는 신뢰 기반 용도에는 암호학적으로 취약하며 사용해서는 안 된다는 것을 확인시켜 줍니다.
이 MD5 생성기를 사용하는 이유
설치나 코드 작성 없이 즉시 MD5 해시를 생성합니다. 텍스트를 붙여넣으면 32자 16진수 다이제스트가 실시간으로 표시됩니다.
MD5 활용 사례
MD5와 다른 해시 알고리즘 비교
MD5는 일반적인 해시 알고리즘 중 가장 빠르고 가장 짧지만 보안 보장이 가장 약합니다. 아래 표는 각 알고리즘의 다이제스트 크기, 표준, 적합한 활용 사례를 비교합니다.
| 알고리즘 | 다이제스트 크기 | 16진수 길이 | 표준 | 최적 용도 |
|---|---|---|---|---|
| MD5 | 128 bits | 32 hex chars | 1992 / RFC 1321 | Checksums, non-security fingerprints |
| SHA-1 | 160 bits | 40 hex chars | 1995 / RFC 3174 | Legacy git commits (being replaced) |
| SHA-256 | 256 bits | 64 hex chars | 2001 / FIPS 180-4 | TLS certificates, blockchain, JWTs |
| SHA-384 | 384 bits | 96 hex chars | 2001 / FIPS 180-4 | Government systems, higher security margin |
| SHA-512 | 512 bits | 128 hex chars | 2001 / FIPS 180-4 | Digital signatures, HMAC with large keys |
| SHA-3 | 256 bits | 64 hex chars | 2015 / FIPS 202 | Post-quantum readiness, backup standard |
| BLAKE3 | 256 bits | 64 hex chars | 2020 | High-performance checksums, Merkle trees |
MD5의 동작 원리
MD5는 Merkle-Damgård 구조를 통해 입력을 처리합니다. 메시지는 512비트의 배수로 패딩되고, 블록으로 분할되며, 각 블록은 입력을 미리 계산된 사인 파생 상수와 혼합하는 4라운드 16개 비트 연산을 거칩니다. 결과는 최종 다이제스트가 되는 128비트 상태입니다.
각 라운드는 네 개의 32비트 상태 워드(A, B, C, D) 중 세 개에 서로 다른 비선형 보조 함수를 적용합니다. 1라운드는 F(B,C,D) = (B AND C) OR (NOT B AND D)를 사용합니다 — 비트 조건부 선택기입니다. 2라운드는 G(B,C,D) = (B AND D) OR (C AND NOT D)를 사용합니다 — 보완적 선택기입니다. 3라운드는 H(B,C,D) = B XOR C XOR D를 사용합니다 — 패리티 함수입니다. 4라운드는 I(B,C,D) = C XOR (B OR NOT D)를 사용합니다 — 비대칭 결합기입니다. 이 네 가지 함수는 입력의 모든 비트가 출력 다이제스트에 영향을 미치도록 하여, 작은 입력 변화가 결과 해시에 크고 예측 불가능한 변화를 일으키는 눈사태 효과를 생성합니다.
MD5: 5eb63bbbe01eeed093cb22bb8f5acdc3
(128 bits = 16 bytes = 32 hex characters)
알고리즘은 다섯 단계로 진행됩니다: (1) 메시지 길이가 512 mod 448이 될 때까지 1비트를 추가한 후 0으로 채웁니다; (2) 원래 메시지 길이를 64비트 리틀 엔디언 정수로 추가합니다; (3) 네 개의 32비트 상태 변수(A, B, C, D)를 고정 상수로 초기화합니다; (4) 각 512비트 블록을 16개 연산의 4라운드(F, G, H, I 비선형 함수 사용)를 거쳐 64개 연산으로 처리합니다; (5) 결과 상태를 누적 합계에 추가하고 최종 128비트 해시를 리틀 엔디언 바이트 순서로 출력합니다.
코드 예제
인기 있는 언어 및 환경에서 MD5 해시를 생성하는 방법입니다. MD5는 브라우저 Web Crypto API에서 사용할 수 없습니다 — 라이브러리 또는 Node.js를 사용하십시오.
// MD5 is not available in Web Crypto API (it only supports SHA-*)
// Use a library like 'js-md5' or the Node.js crypto module
// Node.js (built-in crypto)
const crypto = require('crypto')
const hash = crypto.createHash('md5').update('hello world').digest('hex')
console.log(hash) // → "5eb63bbbe01eeed093cb22bb8f5acdc3"
// With Unicode input
crypto.createHash('md5').update('cafe\u0301').digest('hex')
// → "4fad076bae205e95bec9dacea498e2ab"import hashlib
# Basic MD5 hash
result = hashlib.md5(b'hello world').hexdigest()
print(result) # → "5eb63bbbe01eeed093cb22bb8f5acdc3"
# Hash a string (must encode to bytes first)
text = 'hello world'
hashlib.md5(text.encode('utf-8')).hexdigest()
# → "5eb63bbbe01eeed093cb22bb8f5acdc3"
# Hash a file
with open('file.bin', 'rb') as f:
md5 = hashlib.md5()
for chunk in iter(lambda: f.read(8192), b''):
md5.update(chunk)
print(md5.hexdigest())package main
import (
"crypto/md5"
"fmt"
)
func main() {
data := []byte("hello world")
hash := md5.Sum(data)
fmt.Printf("%x\n", hash)
// → 5eb63bbbe01eeed093cb22bb8f5acdc3
}# Using md5sum (Linux) or md5 (macOS) echo -n "hello world" | md5sum # → 5eb63bbbe01eeed093cb22bb8f5acdc3 - # macOS echo -n "hello world" | md5 # → 5eb63bbbe01eeed093cb22bb8f5acdc3 # Hash a file md5sum package.json # → a1b2c3d4e5f6... package.json # Using openssl (cross-platform) echo -n "hello world" | openssl md5 # → MD5(stdin)= 5eb63bbbe01eeed093cb22bb8f5acdc3