
什么是 SHA-256?
SHA-256(安全哈希算法 256 位)接受任意输入,并产生一个固定的 256 位(64 个十六进制字符)输出,称为摘要或哈希。
SHA-256("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
SHA-256("Hello") = 185f8db32921bd46d35b2e4234ac97a7c3a2d08d3ef5a28c3a6c4e9c8e2e6dd5
SHA-256("hello!") = (完全不同的 64 字符哈希)
SHA-256(1GB 文件) = (仍然恰好 64 个字符)

SHA-256 的特性
确定性: 相同输入始终产生相同哈希。
单向性: 给定哈希,无法计算出原始输入。没有逆向算法——只能暴力破解。
雪崩效应: 改变输入的一个比特会完全改变输出。"hello" 和 "hello1" 产生完全无关的哈希。
抗碰撞性: 从未发现两个不同输入产生相同的 SHA-256 哈希。(MD5 和 SHA-1 存在已知碰撞攻击。)
快速: 现代 GPU 上每秒约 100 亿次哈希。非常适合文件完整性验证。对于密码来说很糟糕(见下文)。

SHA-256 的应用场景
TLS/HTTPS: 每个 HTTPS 证书都使用 SHA-256 签名。TLS 握手使用它进行密钥派生。
比特币: 工作量证明需要找到一个 nonce,使得 SHA-256(SHA-256(block_header)) 以足够多的零比特开头。比特币地址也源自 SHA-256。
Git: 每个提交都由其 SHA 哈希标识。更改提交内容的任何字节都会得到完全不同的哈希。
git log --oneline # 显示提交哈希
git show abc1234 # 通过哈希前缀引用提交
文件完整性: 软件下载包含 SHA-256 校验和,以便验证文件未被损坏或篡改。
sha256sum ubuntu-24.04.iso
# 将输出与下载页面上的官方校验和进行比较
HMAC 签名: SHA-256 用于 HMAC 中对 API 请求和 webhook 进行签名。
crypto.createHmac('sha256', secret).update(payload).digest('hex');

SHA-256 与 MD5 及其他哈希的比较
| 哈希 | 输出 | 被破解? | 速度 | 用途 |
|---|---|---|---|---|
| MD5 | 128 位 | 是(碰撞) | 非常快 | 仅用于遗留校验和 |
| SHA-1 | 160 位 | 是(碰撞) | 快 | 遗留(Git 正在迁移) |
| SHA-256 | 256 位 | 否 | 快 | 通用 |
| SHA-512 | 512 位 | 否 | 在 64 位上更快 | 额外安全余量 |
| SHA-3 | 可变 | 否 | 中等 | 替代设计 |
为什么 SHA-256 不适合密码
SHA-256 在 GPU 上每秒计算约 100 亿次哈希。攻击者利用泄露的数据库可以在数小时内破解 8 位字母数字密码。
应使用专为密码设计的慢速算法:
# 错误:使用 SHA-256 存储密码
import hashlib
password_hash = hashlib.sha256(password.encode()).hexdigest() # 永远不要这样做
# 正确:使用 bcrypt(故意慢速)
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
# bcrypt 在 rounds=12 时 ≈ 330 哈希/秒,而 SHA-256 为 100 亿哈希/秒
# 抗破解能力相差 3000 万倍
计算 SHA-256
// Node.js
const hash = require('crypto').createHash('sha256').update('hello').digest('hex');
// '2cf24dba...'
// 流式处理大文件
const stream = require('fs').createReadStream('large-file.bin');
const hash = require('crypto').createHash('sha256');
stream.pipe(hash).on('finish', () => console.log(hash.digest('hex')));
import hashlib
hashlib.sha256(b'hello').hexdigest()
# '2cf24dba...'
# 文件哈希
with open('file.bin', 'rb') as f:
h = hashlib.file_digest(f, 'sha256')
print(h.hexdigest())
→ 在浏览器中使用 Hash Text Tool 对文本进行 SHA-256 及其他算法的哈希计算。