Hash Identifier
길이와 형식으로 해시 유형 식별 — MD5, SHA-1, SHA-256 등
해시 문자열
해시 식별이란 무엇입니까?
해시 식별은 주어진 다이제스트를 생성한 암호화 해시 알고리즘을 판별하는 과정입니다. MD5, SHA-1, SHA-256과 같은 암호화 해시 함수는 각각 고정 길이의 출력을 생성하며, 출력 길이는 알 수 없는 해시를 식별하는 데 사용되는 주요 신호입니다. 데이터베이스 덤프, 설정 파일, 또는 API 응답에서 16진수 문자열을 접할 때, 해시 식별 도구는 어떤 알고리즘이 이를 생성했는지 알려줍니다.
모든 해시 알고리즘은 임의의 입력 데이터를 다이제스트라고 하는 고정 크기의 출력으로 변환합니다. MD5는 항상 128비트(32개의 16진수 문자)를 생성하고, SHA-1은 항상 160비트(40개의 16진수 문자)를 생성하며, SHA-256은 항상 256비트(64개의 16진수 문자)를 생성합니다. 이 결정론적 출력 길이 덕분에 원본 입력이나 해싱 코드에 접근하지 않고도 알고리즘 식별이 가능합니다.
길이만으로는 항상 확정적으로 식별할 수 없습니다. 여러 알고리즘이 동일한 출력 크기를 공유하는 경우가 있습니다. 예를 들어, SHA-256과 SHA3-256은 모두 64자리 16진수 다이제스트를 생성합니다. 이러한 경우, 해시 식별기는 발생 빈도에 따라 순위가 매겨진 후보 알고리즘 목록을 제공합니다. 소스 시스템, 인코딩 형식(hex 대 Base64), 알고리즘 접두사(bcrypt의 경우 '$2b$'와 같은) 등의 맥락 단서로 가능성을 더욱 좁힐 수 있습니다.
해시 식별기를 사용하는 이유
알 수 없는 해시는 보안 감사, 데이터베이스 마이그레이션, 포렌식 분석 과정에서 자주 등장합니다. 해시 식별기는 추측의 필요성을 없애고 수초 내에 올바른 알고리즘을 알려줍니다.
해시 식별기 활용 사례
해시 알고리즘 길이 참조표
아래 표는 각 주요 해시 알고리즘의 출력 크기를 비트, 16진수 문자 수, 원시 바이트로 매핑합니다. 이것은 해시 식별 도구에서 사용하는 기본 조회 표입니다. 여러 알고리즘이 동일한 16진수 길이를 공유하는 경우, 이를 구별하기 위한 추가적인 맥락이 필요합니다.
| 알고리즘 | 비트 | 16진수 문자 수 | 바이트 | 비고 |
|---|---|---|---|---|
| MD5 | 128 | 32 | 16 | Broken — collisions trivial since 2004 |
| SHA-1 | 160 | 40 | 20 | Deprecated — SHAttered attack (2017) |
| SHA-224 | 224 | 56 | 28 | Truncated SHA-256; rarely used standalone |
| SHA-256 | 256 | 64 | 32 | Current standard; TLS, Git, Bitcoin |
| SHA-384 | 384 | 96 | 48 | Truncated SHA-512; CNSA Suite approved |
| SHA-512 | 512 | 128 | 64 | Maximum SHA-2 output; large-data hashing |
| SHA3-256 | 256 | 64 | 32 | Keccak-based; NIST alternative to SHA-2 |
| SHA3-512 | 512 | 128 | 64 | Keccak-based; highest SHA-3 strength |
| RIPEMD-160 | 160 | 40 | 20 | Used in Bitcoin address derivation |
| BLAKE2s | 256 | 64 | 32 | Faster than SHA-256; 256-bit output |
해시 길이 모호성 해소
일부 16진수 길이는 여러 알고리즘에 해당합니다. 가장 흔한 두 가지 모호한 경우는 64자리 해시(SHA-256 대 SHA3-256)와 40자리 해시(SHA-1 대 RIPEMD-160)입니다. 길이만으로는 충분하지 않을 때 이를 구별하는 방법을 설명합니다.
코드 예제
아래는 네 가지 언어로 작성된 16진수 길이 기반 해시 식별의 실제 구현 예제입니다. 각 함수는 16진수 인코딩을 검증하고, 문자 수를 조회하여 일치하는 모든 알고리즘을 반환합니다.
function identifyHash(hex) {
const len = hex.length
const isHex = /^[0-9a-fA-F]+$/.test(hex)
if (!isHex) return ['Not a hex-encoded hash']
const map = {
32: ['MD5'],
40: ['SHA-1', 'RIPEMD-160'],
56: ['SHA-224', 'SHA3-224'],
64: ['SHA-256', 'SHA3-256', 'BLAKE2s'],
96: ['SHA-384', 'SHA3-384'],
128: ['SHA-512', 'SHA3-512', 'BLAKE2b'],
}
return map[len] || [`Unknown (${len} hex chars)`]
}
identifyHash('d41d8cd98f00b204e9800998ecf8427e')
// → ["MD5"]
identifyHash('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')
// → ["SHA-256", "SHA3-256", "BLAKE2s"]import re
HASH_LENGTHS = {
32: ['MD5'],
40: ['SHA-1', 'RIPEMD-160'],
56: ['SHA-224', 'SHA3-224'],
64: ['SHA-256', 'SHA3-256', 'BLAKE2s'],
96: ['SHA-384', 'SHA3-384'],
128: ['SHA-512', 'SHA3-512', 'BLAKE2b'],
}
def identify_hash(hex_string: str) -> list[str]:
hex_string = hex_string.strip()
if not re.fullmatch(r'[0-9a-fA-F]+', hex_string):
return ['Not a hex-encoded hash']
return HASH_LENGTHS.get(len(hex_string), [f'Unknown ({len(hex_string)} hex chars)'])
identify_hash('da39a3ee5e6b4b0d3255bfef95601890afd80709')
# → ['SHA-1', 'RIPEMD-160']
identify_hash('a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a')
# → ['SHA-256', 'SHA3-256', 'BLAKE2s']package main
import (
"fmt"
"regexp"
)
var hexPattern = regexp.MustCompile("^[0-9a-fA-F]+$")
var hashLengths = map[int][]string{
32: {"MD5"},
40: {"SHA-1", "RIPEMD-160"},
56: {"SHA-224", "SHA3-224"},
64: {"SHA-256", "SHA3-256", "BLAKE2s"},
96: {"SHA-384", "SHA3-384"},
128: {"SHA-512", "SHA3-512", "BLAKE2b"},
}
func identifyHash(hex string) []string {
if !hexPattern.MatchString(hex) {
return []string{"Not a hex-encoded hash"}
}
if algos, ok := hashLengths[len(hex)]; ok {
return algos
}
return []string{fmt.Sprintf("Unknown (%d hex chars)", len(hex))}
}
func main() {
fmt.Println(identifyHash("d41d8cd98f00b204e9800998ecf8427e"))
// → [MD5]
}#!/bin/bash
# Identify a hash from the command line by character count
hash="$1"
if [[ ! "$hash" =~ ^[0-9a-fA-F]+$ ]]; then
echo "Not a hex-encoded hash"
exit 1
fi
len=${#hash}
case $len in
32) echo "MD5 (128-bit)" ;;
40) echo "SHA-1 or RIPEMD-160 (160-bit)" ;;
56) echo "SHA-224 or SHA3-224 (224-bit)" ;;
64) echo "SHA-256 or SHA3-256 (256-bit)" ;;
96) echo "SHA-384 or SHA3-384 (384-bit)" ;;
128) echo "SHA-512 or SHA3-512 (512-bit)" ;;
*) echo "Unknown hash length: $len chars" ;;
esac
# Usage: ./identify.sh d41d8cd98f00b204e9800998ecf8427e
# → MD5 (128-bit)