什么是 Secure Hash Algorithm (SHA)?
SHA (安全哈希算法) 是由 **NIST (美国国家标准与技术研究院)** 发布的**密码学哈希函数族**标准 (FIPS 180)。它将任意长度的输入消息映射为**固定长度的输出值 (哈希值/摘要/指纹)**,具有**单向性**、**确定性**、**抗碰撞**等特性,广泛用于**完整性校验、数字签名、证书、密码存储、区块链、TLS/SSL、IPsec、SSH** 等核心安全场景。
核心安全属性
| 属性 | 定义 | 安全含义 |
| Pre-image Resistance (原像抗性) | 给定 h,难以找到 m 使 H(m)=h | 单向性:从摘要反推原文不可行 → 适合存密码哈希 |
| Second Pre-image Resistance (第二原像抗性) | 给定 m1,难以找到 m2≠m1 使 H(m2)=H(m1) | 防止替换文件而保持相同哈希 → 完整性保护 |
| Collision Resistance (抗碰撞性) | 难以找到任意 m1≠m2 使 H(m1)=H(m2) | 防止构造两份不同内容同哈希文件 → 数字签名/证书安全基础 |
| Avalanche Effect (雪崩效应) | 输入 1 bit 变化 → 输出 ~50% bit 翻转 | 输出看似随机,无规律可循 |
SHA 家族版本演进
| 算法 | 发布年份 | 输出长度 | 分组/字长 | 轮数 | 状态 | 典型用途 |
| SHA-0 (SHA) | 1993 | 160-bit | 512/32 | 80 | **已弃用** (发现弱点) | 历史遗留 |
| SHA-1 | 1995 | 160-bit | 512/32 | 80 | **已弃用/禁用** (SHAttered 碰撞攻击 2017 实战) | Git (过渡中), 旧证书, 遗留系统 |
| SHA-224 | 2001 | 224-bit | 512/32 | 64 | 安全 (SHA-2 族) | 兼容 3DES/112-bit 安全级 |
| SHA-256 | 2001 | 256-bit | 512/32 | 64 | **主流推荐** (SHA-2 族核心) | TLS 1.2/1.3, Bitcoin, 证书, 签名, 密码哈希 (PBKDF2) |
| SHA-384 | 2001 | 384-bit | 1024/64 | 80 | 安全 (SHA-2 族) | 高安全级, 兼容 192-bit 安全级 |
| SHA-512 | 2001 | 512-bit | 1024/64 | 80 | **高性能 64-bit 平台首选** | 高安全级, 密码哈希 (bcrypt/scrypt/Argon2 内部) |
| SHA-512/224 | 2012 | 224-bit | 1024/64 | 80 | 安全 | 截断版 SHA-512, 不同 IV |
| SHA-512/256 | 2012 | 256-bit | 1024/64 | 80 | 安全 | 截断版 SHA-512, 不同 IV |
| SHA-3 (Keccak) | 2015 | 224/256/384/512 | 1600 (Sponge) | 24 | **最新标准** (FIPS 202), 结构完全不同 | 新设计、抗侧信道、硬件友好、区块链 (Ethereum Keccak-256) |
| SHAKE128/256 (XOF) | 2015 | 可变长度 | 1600 | - | 可扩展输出函数 | 密钥派生、随机数生成、流密钥 |
SHA-1 为何被淘汰?
- 2005 年理论碰撞攻击复杂度降至 2^69
- 2017 年 **SHAttered** (Google + CWI) 实战构造两个不同 PDF 同 SHA-1,复杂度 2^63.1
- 主流浏览器 (Chrome, Firefox, Edge, Safari) **已停止信任 SHA-1 证书**
- NIST 要求 **2016 年后不再用于数字签名生成**
- Git 正在迁移到 SHA-256 (过渡期双哈希)
SHA-256 为何成为黄金标准?
- 无已知实用碰撞/原像攻击 (最佳已知攻击复杂度仍 2^256/2^128)
- 32-bit/64-bit CPU 均高效 (ARM, x86, RISC-V 都有硬件加速指令: SHA-NI, ARMv8 SHA)
- TLS 1.2/1.3, IKEv2, IPsec, SSH, DKIM, JWT, Bitcoin, Git (新版) 标准算法
- NIST SP 800-57 推荐: 2030 年前 112-bit 安全级 (SHA-224/256), 2030 后 128-bit+ (SHA-256/384/512, SHA-3)
SHA-3 (Keccak) 的独特价值
- Sponge 构造: 吸收-挤出,任意长度输入/输出,非 Merkle-Damgård 结构
- **避免 SHA-1/2 同构风险**: 若 SHA-2 发现弱点,SHA-3 独立幸存
- **抗侧信道**: 固定操作序列,易做恒时实现
- **硬件极高效**: ASIC/FPGA 面积小、功耗低、吞吐高
- **XOF (SHAKE)**: 任意输出长度,替代 KDF/Stream Cipher
当前 SHA-2 (尤其是 SHA-256/512) 仍是主流生产标准;SHA-3 用于新设计、高安全要求、硬件实现、或作为算法多样性储备。
SHA 在网络安全协议中的应用
| 协议/场景 | SHA 角色 | 典型算法 |
| TLS 1.2/1.3 (HTTPS) | PRF (伪随机函数), 证书签名, 密钥派生, Finished 验证 | SHA-256, SHA-384 |
| IPsec (ESP/AH) | 完整性校验 (HMAC-SHA), IKE 密钥派生 | SHA-256, SHA-384, SHA-512 |
| SSH | 密钥交换 (KEX) 哈希, 公钥指纹, 完整性 | SHA-256, SHA-512 |
| 数字证书 (X.509) | CA 签名算法 (RSA/ECDSA + SHA-256/384/512) | sha256WithRSAEncryption, ecdsa-with-SHA256 |
| DNSSEC | 区域签名 (ZSK/KSK), DS 记录哈希 | SHA-256 (Algorithm 8/13/14) |
| DKIM/DMARC/SPF | 邮件签名哈希 | SHA-256 (rsa-sha256) |
| 代码签名 / 供应链 | 文件完整性哈希 (SLSA, Sigstore, Cosign) | SHA-256 |
| 区块链 (Bitcoin) | 工作量证明 (双 SHA-256), 地址生成 (RIPEMD160(SHA-256(pubkey))) | SHA-256d |
| 区块链 (Ethereum) | 地址, 交易哈希, 状态树 (Keccak-256) | Keccak-256 (SHA-3 变体) |
| 密码存储 (KDF) | PBKDF2-HMAC-SHA256/512, scrypt (内部用 SHA-256), Argon2 (内部用 BLAKE2) | SHA-256/512 作为底层原语 |
| 文件完整性 (AIDE, Tripwire, rpm -V, debsums) | 基线哈希对比 | SHA-256, SHA-512 |
密码存储特别说明:别直接用 SHA-256!
SHA-256 太快了 (GPU 可达 100+ GH/s),直接哈希密码极易被彩虹表/暴力破解。
必须使用慢速 KDF (Key Derivation Function):
- Argon2id (首选, 2015 PHC 冠军, 记忆困难, 抗 GPU/ASIC)
- scrypt (记忆困难, 早于 Argon2)
- bcrypt (基于 Blowfish, 可配置 cost factor, 广泛支持)
- PBKDF2-HMAC-SHA256/512 (仅作兼容/合规, 迭代数 ≥ 600,000, 纯 CPU 密集型)
常见编程语言调用示例
Python (hashlib)
import hashlib
data = b"Hello, Network Security!"
print("SHA-256:", hashlib.sha256(data).hexdigest())
print("SHA-512:", hashlib.sha512(data).hexdigest())
print("SHA3-256:", hashlib.sha3_256(data).hexdigest())
# 密码哈希示例
import argon2
ph = argon2.PasswordHasher()
hash = ph.hash("my_secure_password")
ph.verify(hash, "my_secure_password") # 验证
OpenSSL CLI
# 文件哈希
openssl dgst -sha256 file.bin
openssl dgst -sha3-256 file.bin
# HMAC
echo -n "message" | openssl dgst -sha256 -hmac "secret_key"
# 密码哈希 (PBKDF2)
openssl kdf -keylen 32 -kdfopt pass:password -kdfopt iter:600000 -kdfopt digest:SHA256 PBKDF2
Linux 命令行
sha256sum file.txt
sha512sum file.txt
sha3-256sum file.txt # 需 coreutils 9.0+
# 验证
echo "expected_hash file.txt" | sha256sum -c
总结
SHA 是现代密码学基石。**SHA-256 是当前通用首选** (性能/安全/生态平衡最佳);**SHA-512 适合 64-bit 高性能场景**;**SHA-3/Keccak 提供算法多样性与抗侧信道优势**;**SHA-1 彻底禁用**。**切记:存密码别用裸 SHA,要用 Argon2id/bcrypt/scrypt/PBKDF2**。理解哈希属性、选型依据、协议中的角色,是网络安全工程师的基本功。