SHA-256 是什么
SHA-256 是 FIPS 180-4 定义的密码学哈希函数:把任意长度输入压缩成 256 位(32 字节)摘要,内部块长 512 位、64 轮压缩,状态为 8 个 32 位字。它采用 Merkle-Damgard 迭代结构,任何一位输入变化都会让输出雪崩式改变,且无法从摘要反推原文。证书签名、TLS 握手校验、HMAC、文件校验与内容寻址里都大量使用它。
基本信息
| 标准 | FIPS 180-4 §6.2 |
|---|---|
| 输出长度 | 256 位(32 字节) |
| 块长度 | 512 位(64 字节) |
| 字长 / 轮数 | 32 位 / 64 轮 |
| 内部状态 | 8 个 32 位字 |
| 安全强度 | 抗碰撞约 128 位、抗前像约 256 位 |
| 常见实现 | openssl dgst、sha256sum、语言标准库 hashlib 等 |
典型使用场景
- 文件完整性校验:发布固件或 ISO 时附带摘要,下载方比对是否被意外损坏
- 数字签名摘要:证书、代码签名、时间戳都先用 SHA-256 压缩原文再签名
- 消息认证:HMAC-SHA256、JWT 的 HS256、开放平台接口签名
- TLS 1.3 密钥派生:HKDF 以 SHA-256 为底层哈希,Finished 消息也用它校验
- 口令派生:PBKDF2-HMAC-SHA256 是合规场景常见的存储方案
- 内容寻址与去重:以摘要作为对象键,天然实现相同内容只存一份
计算与校验
计算与校验
# 计算字符串摘要:echo -n 避免把换行也算进输入
printf '%s' 'hello' | openssl dgst -sha256
# 生成校验清单并回验,-c 会逐条输出 OK / FAILED
sha256sum firmware.bin > firmware.sha256
sha256sum -c firmware.sha256
# 批量校验目录下所有文件,失败时不中断
sha256sum -c firmware.sha256 --ignore-missing --quiet
# 输出二进制摘要再做 Base64,便于放进 JSON 或请求头
openssl dgst -sha256 -binary firmware.bin | openssl base64
# 只取摘要值,方便脚本比对
sha256sum firmware.bin | cut -d' ' -f1输出逐列读法
| 字段 | 含义 | 正常与异常表现 |
|---|---|---|
| 64 位十六进制 | 摘要值,大小写不影响含义 | 长度不足 64 位说明被截断或根本不是 SHA-256 |
| 文件名 | 被校验对象,二进制模式会带前缀星号 | 用 -c 校验时文件名必须与实际一致,否则报找不到 |
| OK | 该文件摘要与清单一致 | 唯一可接受的正常结果 |
| FAILED | 内容与清单不符 | 可能是下载损坏、被篡改或清单本身过期 |
| WARNING: 1 line is improperly formatted | 清单里有空行或格式错误 | 常见于手工编辑过的清单,需先修正清单 |
换行与编码会改变摘要:Windows 的 CRLF 文本与 Linux 的 LF 文本摘要不同,跨平台校验前先统一换行;比较摘要时也应按字符串精确比对,不要忽略大小写或空格。
哈希不是签名。SHA-256 没有密钥,任何人都能重算,因此只能发现传输损坏,无法证明来源。要防篡改与伪造,需要用 HMAC(共享密钥)或非对称签名(私钥签名、公钥验签)。
性能对照
性能对照
# 64 位平台上 SHA-512 往往比 SHA-256 更快,但兼容性与长度需求优先
openssl speed -elapsed -evp sha256
openssl speed -elapsed -evp sha512
# 处理大文件时用流式接口,避免整文件读入内存
openssl dgst -sha256 /data/big.iso不要用单轮 SHA-256 存口令:GPU 每秒可算数十亿次,离线爆破成本极低。口令存储应使用 Argon2id、scrypt 或高迭代 PBKDF2;SHA-256 在此只作为 KDF 内部组件出现。
工程实践要点
- 校验清单本身要随发布物一起签名:清单可被替换时,比对摘要就失去了防篡改意义
- 摘要的十六进制大小写不影响含义,但脚本比对要统一格式与分隔符,避免人工目视漏字符
- 下载后先校验再解压或解析,不要在未校验的数据上直接跑解析器与安装程序
- 接口签名场景要固定参数拼接顺序与编码,参数顺序变化会让同一请求得到不同摘要
- 排查问题时日志只记录摘要与输入长度,不要打印原文,避免把敏感内容写进日志