先按十六进制长度初筛
| 算法 | 摘要位数 | 常见十六进制长度 | 安全判断 |
|---|---|---|---|
| MD5 | 128 bit | 32 | 已不适合抗碰撞用途 |
| SHA-1 | 160 bit | 40 | 已不适合抗碰撞用途 |
| SHA-256 | 256 bit | 64 | 常用于完整性校验 |
| SHA-512 | 512 bit | 128 | 输出更长,属于 SHA-2 |
如果字符串使用 Base64 表示、带盐、带算法前缀,长度会不同。Linux 密码格式、bcrypt、scrypt、Argon2 等还会包含参数,因此不能套用上表直接判断。
三个容易混淆的性质
原像阻力
给定摘要,很难找到一个输入产生它。这里的“难”依赖输入空间;四位 PIN 的空间很小,即使使用 SHA-256 也能被快速枚举。
第二原像阻力
给定一个输入,很难找到另一个不同输入产生相同摘要。
碰撞阻力
很难找到任意两个不同输入具有相同摘要。MD5 和 SHA-1 的主要问题在这里,因此不能用于现代证书签名或需要抗碰撞的安全设计。
CTF 中怎么用
拿到未知摘要后,先记录长度、字符范围和上下文。若题目提供候选明文,不需要“解密”哈希,只要使用相同算法计算候选值并比较。
candidate: flag{hashes_are_one_way}
sha256: 重新计算后与题目摘要做精确比较文件取证中也是同样逻辑:计算下载文件的 SHA-256,与发布者给出的值比较。匹配说明字节级内容一致,不说明文件一定安全。
盐不会隐藏算法
盐用于让相同密码得到不同结果并抵抗预计算表。验证时必须按同一格式把盐、参数和候选值交给对应算法,而不是简单拼接后猜测。
常见错误
- 把“在线哈希查询命中”理解成哈希被逆向;实际通常是数据库已有明文。
- 使用 MD5 校验可下载文件,却忽略攻击者可能同时替换文件和校验值。
- 只看 32 位长度就断言是 MD5;它也可能是随机标识或截断摘要。
- 对密码直接做一次 SHA-256;密码存储应使用专门的慢哈希方案。
判断清单
- 确认表示形式:Hex、Base64 还是带前缀格式。
- 记录长度和上下文。
- 列出可能算法,不只保留一个答案。
- 用已知样例或候选输入验证。
- 在报告中写“疑似”或“已验证”,不要混用。