使用方法
- 文本框里已经放好一段示例原文,它是 128 个 UTF-8 字节、26 个汉字;页面打开时结果区显示的就是它的摘要
cf01be2838769ef7aa8ceaef880fa1c24769f632923a23d3aa36d5010864d4e5。换成你的内容后结果自动重算。 - 文本框里按 Ctrl + Enter(macOS 用 Cmd + Enter)立刻重算;Enter 留给换行。做接口签名校验时,请求体里的换行和空格同样参与摘要,不能被快捷键吃掉。
- 「盐值」默认填
liuquan-2026,只为了方便演示可复现。真实系统里盐是每条记录随机生成的,长度一般 8~16 字节,和摘要一起明文存在数据库里——盐不是秘密,它的作用是让同一个口令在不同记录里算出不同的摘要。 - 「PBKDF2 迭代次数」默认
10000,可填 1~1000000。它决定慢哈希要重复多少轮,改这个值只会改变第三张卡片里的 PBKDF2 结果,不影响前面那张单轮 SHA-256 摘要。 - 点「复制摘要」默认复制单轮 SHA-256 摘要;点「载入示例」还原全部默认值;点「清空原文」清空。下方对照表旁边还有「加载更多」「复制对照表(TSV)」「导出 CSV(带 BOM)」三个按钮。
这个 SHA256加密 工具能解决什么问题
一是做真正能防篡改的完整性校验。发布页给的出现 SHA-256,你本地算一遍比对,既能挡住传输损坏,也能挡住刻意构造的同摘要替换——这一点是 MD5 做不到的:MD5 在 2004 年之后可以被主动造出一对内容不同、摘要相同的消息(公开样本各 128 字节、只差 6 个二进制位,摘要同为 79054025255fb1a26e4bc422aef54eb4),而 SHA-256 至今没有已知的实用碰撞方法。
二是看清「加盐」到底改变了什么。同样的口令不加盐时,全世界算出来的 SHA-256 都一样,一张彩虹表就能通吃;加了盐之后,同一份口令在不同站点、不同用户上得到完全不同的摘要。页面下方的 50 行对照表把这一点逐行摊开:123456 的裸摘要是 8d969eef6eca…,加盐后变成 53070b0561bf…,而换成另一个盐又会是第三个数。
三是把一个「太快的哈希」变慢。SHA-256 的设计目标是高速,一块普通显卡一秒能算几十亿次,用来存口令等于给攻击者送便利。本页用 PBKDF2-HMAC-SHA256 演示慢哈希:迭代 10000 次就把单次校验的代价放大 10000 倍,迭代 600000 次(OWASP 对 PBKDF2-HMAC-SHA256 的建议值)则放大 60 万倍,而合法用户只是多等几十毫秒。
四是理解长度扩展攻击这类结构性问题。SHA-256 和 MD5 一样属于 Merkle–Damgård 结构,攻击者在知道 H(secret || msg) 和 secret 长度的情况下,不需要知道 secret 就能续算出 H(secret || msg || padding || append)。本页用具体数字把这条攻击走完一遍,说明为什么做消息认证必须用 HMAC 而不是直接拼串哈希。
这个 SHA256加密 工具不做这些事:不做反向解密(摘要不可逆)、不做 JWT 的签名验签、不做口令强度评分、不做哈希类型识别。要解开 JWT 的头部与载荷请看页面底部的「JWT解码」;要估计一条已有口令被暴力破解需要多久,请看「暴力时间计算器」。
算法原理与几个关键参数
它遵循的标准与家族位置。SHA-256 由美国 NIST 在 FIPS 180-4 中定义,属于 SHA-2 家族(同家族还有 SHA-224、SHA-384、SHA-512,其中 224 与 256 共用 32 位字、384 与 512 共用 64 位字)。本页的实现按 FIPS 180-4 逐轮用纯 JavaScript 写出,不依赖任何第三方库,也不依赖浏览器的 Web Crypto 接口——后者虽然提供 SHA-256,但拿不到中间状态,也没法在上面自己搭 PBKDF2 的轮次控制。
为什么输出是 256 位。256 位 = 32 字节 = 64 个十六进制字符,由 8 个 32 位寄存器 A~H 拼接而成。初值取自前 8 个质数(2、3、5、7、11、13、17、19)平方根小数部分的前 32 位,例如 A 是 0x6a09e667。相比 MD5 只有 4 个 32 位寄存器,寄存器数量翻倍带来两个效果:摘要空间从 2128 涨到 2256 ≈ 1.1579×1077,而且轮函数里多了 Σ 与 σ 两组多位移位异或,差分传播更难控制。
补位与分组:和 MD5 同构,但字序是反的。补位规则一样是先补一个 0x80、再补若干 0x00、最后追加原始位长,区别在于这个 64 位长度是大端写入的,分组内的 16 个 32 位字也按大端切分。这一点是最容易写错的地方:MD5 全程小端,SHA-1 与 SHA-256 全程大端,把两者混用会得到一串「看着像 MD5 又不像」的错值。补位同样制造边界——输入 55 字节时 55+1+8=64 恰好 1 个分组,输入 56 字节时溢出到 2 个分组,输入 120 字节时 120+1+8=129 溢出到 3 个分组。本页的示例原文是 128 字节,结果区那一栏显示的就是 3。
每个分组 64 轮与 64 个常量。消息扩展阶段把 16 个字扩成 64 个字(每个新字由前 15、前 2、前 7、前 16 个字的 σ 变换与加法得到),压缩阶段则做 64 轮,每轮用 6 个逻辑运算与 8 个寄存器轮转。常量表 K[i] 共 64 个,取自前 64 个质数立方根小数部分的前 32 位,同样只是「看起来随机」的固定值,不含任何秘密。因为整套运算只用整数加、循环右移和异或,所以输出恒长、结果确定,不存在浮点误差问题。
长度扩展攻击:用数字走一遍。SHA-256 与 MD5 一样是 Merkle–Damgård 结构,压缩函数用的是 Davies–Meyer 构造——把前一块的中间状态当作密钥、消息块当作待加密内容,再与状态异或,这个「状态既当输入又当输出」的设计正是长度扩展能成立的原因。把 secret 设为 10 个字节、msg 设为 21 个字节,服务端公开 SHA-256(secret || msg) = 35f830db7e101380b440b797462d2e14fa2d70a5cc9c0d63a03a31b1f900158b。攻击者不需要知道 secret,只要知道它的长度,就能把状态直接当作新的初始向量,续算「原消息的补位 + 附加内容」——本页复算脚本里附加 &role=admin 后得到一条 75 字节的新消息,其摘要 90bb758aa8d202287349c726320095d3c89d854ea11a3cf4afabf264cf3e1557 会被服务端判定为合法。结论:认证标签必须用 HMAC-SHA256,而不是把密钥拼在消息前面再哈希。HMAC 用 H((K⊕opad) || H((K⊕ipad) || msg)) 的双层结构把长度扩展这条路径堵死。
加盐:解决的是「预计算」,不是「穷举」。不加盐时,摘要只取决于口令本身,于是攻击者可以事先把几亿条常见口令的 SHA-256 算好做成一张表,拿到泄露的摘要直接查表。加盐之后每条记录的摘要都被盐「错开」,攻击者必须针对每一条盐重新算一遍,一张表覆盖所有用户的时代结束。这才是「每个用户必须用不同的随机盐」的真正原因:共用一个固定盐,等于只把彩虹表整体平移了一个偏移量,仍然可以一次算好、全部命中。
慢哈希:为什么还要再叠一层迭代。加盐挡不住「拿到那一条记录、针对它的盐穷举弱口令」,因为 SHA-256 太快了,一条记录配一个盐也只是多算一次。于是人们让单次校验本身变贵:PBKDF2 把 U1 = HMAC(口令, 盐 || 块序号),然后反复 Uj = HMAC(口令, U(j-1)),最后把所有 U 异或起来当结果,迭代 N 次就把单次校验的代价乘以 N。三个参数各管一件事:dkLen(本页取 32 字节,与 SHA-256 输出等长)、盐、迭代次数 N。新一代算法在此基础上又加了内存成本——bcrypt 基于 Blowfish 改造的 EksBlowfish,用 cost 参数控制 2cost 轮;scrypt 强制占用大块内存,让显卡和 ASIC 的优势变小;Argon2(2015 年密码哈希竞赛 PHC 的优胜者,分 Argon2d / Argon2i / Argon2id 三种变体)可以同时调内存、时间与并行度三个维度,是目前的口令存储首选。
完整示例(数值均为本页真机算出)
示例条件就是页面打开时的默认状态:原文为 柳泉工具 SHA256加密(sha256jiami)示例:Hello, 柳泉 2026-10-01. 加一个换行再加 第二行说明换行与空格同样进入摘要。,共 128 个 UTF-8 字节、26 个汉字;盐取 liuquan-2026,迭代次数取 10000。结果如下:
- SHA-256 摘要:
cf01be2838769ef7aa8ceaef880fa1c24769f632923a23d3aa36d5010864d4e5,固定 64 个十六进制字符; - 摘要 Base64:
zwG+KDh2nveqjOrviA+hwkdp9jKSOiPTqjbVAQhk1OU=,正好 44 个字符(32 字节按 3 字节一组编码,末尾一个=补位); - PBKDF2-HMAC-SHA256(盐 liuquan-2026,10000 次):
5bda76fc7549fdad2c227da353714dade9294ec7d88c0f26a05b72f7d0dc33d2; - UTF-8 字节数:128;补位后的分组数:128+1+7 = 136,向上取整到 64 的整数倍是 192 字节,即 3 个 512 位分组。
同一条原文换盐或换迭代次数,结果立刻分叉,这三个值都可以在页面上直接复现:
- 盐填空、迭代 10000 次:
d102bd741ed7fd47e3195ac4a4338920b56e0e4b09c7d444c4895a7c3ec3bd4d; - 盐改成
liuquan-2027、迭代仍是 10000 次:5e7377ae548a6914a4705b2fa2ae0611bc30640fc9158af3c2d102949520dc9b; - 盐仍是
liuquan-2026、迭代提到 600000 次(OWASP 建议档):06eb69e923c7ff8a5e7cf3d06c87a7a50b8ccbc735ed85e5b2016ad12fb14f9e。
拿公开测试向量交叉验证:FIPS 180-4 附录里空串的 SHA-256 是 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,abc 是 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad,abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq 是 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1,这三个都可以直接粘进上面的文本框复现;第四条是一百万个 a,结果是 cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0,它超过了本页 20 万字符的输入上限,只能在离线脚本里验证,本页的纯 JavaScript 实现同样通过了它。四条全部命中,也就是说你在别处看到的同算法结果应当与本页逐位相同。
输入范围与对照表
输入范围。原文上限 20 万个字符(按 UTF-16 码元计),超出后文本框不再接收新字符;盐值最长 64 个字符;PBKDF2 迭代次数 1~1000000 的整数。这里的 64 不是随手定的:HMAC 的密钥块长度恰好是 64 字节,密钥超过 64 字节时会先被哈希一次再使用,把盐限制在 64 以内可以让「盐就是密钥」的演示路径保持直观。
第一张表是四个常见摘要算法对同一输入 abc 的输出,用来确认算法换了结果就完全不同:
| 算法 | 输出位长 | 十六进制字符 | 字节 | 输入 abc 的结果 |
|---|---|---|---|---|
| MD5 | 128 位 | 32 | 16 | 900150983cd24fb0d6963f7d28e17f72 |
| SHA-1 | 160 位 | 40 | 20 | a9993e364706816aba3e25717850c26c9cd0d89d |
| SHA-256(本页) | 256 位 | 64 | 32 | ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad |
| SHA-512 | 512 位 | 128 | 64 | ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a… |
第二张表把「裸哈希 / 加盐 / 加盐再迭代」三种配置放在一起,看它们分别挡得住什么。倍数一栏是相对单轮无盐哈希的计算成本:
| 配置 | 彩虹表能否直接命中 | 相对计算成本 | 说明 |
|---|---|---|---|
| 裸 SHA-256(无盐、单轮) | 能,一次算好全网通吃 | 1× | 同一个口令在任何站点得到同一个值,最不该用的一种 |
| 加随机盐 + 单轮 SHA-256 | 不能,必须逐条重算 | 约 1× | 挡住了预计算表,但单轮太快,弱口令仍会被秒破 |
| 加盐 + PBKDF2 迭代 10000 次(本页默认) | 不能 | 10000× | 单次校验成本放大四个数量级,演示与小型站点够用 |
| 加盐 + PBKDF2 迭代 600000 次(OWASP 建议) | 不能 | 600000× | 合法用户多等几十毫秒,攻击者的字典穷举被拖慢 60 万倍 |
| bcrypt / scrypt / Argon2 | 不能 | 可调,且额外吃内存 | 不只用时间成本,还用内存与并行度成本压制显卡与 ASIC |
第三张表就是页面上方那张 50 行的对照表,列出 50 个公开泄露字典里的高频口令、它们的裸 SHA-256 前 12 位、以及用固定盐 liuquan-2026 加盐后的前 12 位。前 12 位只有 48 bit,用它只是为了排版紧凑和快速比对,正式校验请始终使用完整的 64 位摘要。
顺便把成本算清楚:256 位摘要空间是 2256 ≈ 1.1579×1077。按每秒 1021 次(比特币全网曾达到的算力量级)穷举一条原像,需要约 3.67×1048 年;即便只用生日界找一对碰撞,也要约 2128 ≈ 3.4028×1038 次运算。这是 SHA-256 至今站稳的根本原因,也和 MD5 的 264 生日界拉开了天壤之别。
结果边界与取舍说明
- 输出长度恒定,没有舍入。SHA-256 全程是 32 位无符号整数运算,输出固定 64 个十六进制字符,不存在小数位取舍或精度溢出。
- 迭代次数直接换算成耗时。本页的 PBKDF2 是纯 JavaScript 实现,比原生代码慢一个数量级左右,所以默认取 10000 而不是 OWASP 建议的 600000。把迭代次数拉到 100 万,纯 JS 下要等几秒;结果区会显示本机实测的单次耗时,数字随机器性能浮动,但倍率关系是线性的:迭代次数翻倍,耗时基本也翻倍。
- 盐必须随机、必须唯一、不需要保密。盐的作用是让预计算失效,所以重点是「每条记录都不同」,而不是「藏起来」。演示用的固定盐只是为了让三组数值可以复现,直接搬去生产等于没有加盐。
- 单轮 SHA-256 依然不能存口令。本页给出的单轮摘要适合做文件指纹、接口签名与防篡改校验;一旦用途变成「存口令」,就必须切到加盐的慢哈希,因为 SHA-256 的运算速度正是攻击者想要的。
- 前 12 位是截断,不是另一种算法。截断只保留 48 bit,碰撞概率远高于完整摘要,只能用于表格里的快速对照,不能替代完整摘要做校验。
- 空输入也有摘要。空字符串的 SHA-256 是
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,不是空值也不是报错。只有参数写错时才会拦截:迭代次数不是 1~1000000 的整数,或者盐超过 64 个字符。 - 确定性带来可重放,也带来泄露风险。同一个盐加同一个口令永远得到同一个摘要,这是服务端能验证口令的前提;但反过来,如果摘要泄露、盐也泄露,攻击者就能离线穷举。所以盐要跟着摘要一起存,而数据库本身必须严格保护。
- 和 MD5 的分工要说清楚。MD5 输出 128 位、已被主动碰撞攻破,只适合兼容老系统或非对抗性的快速比对;SHA-256 输出 256 位、目前没有实用碰撞方法,是防篡改、数字签名、证书指纹与 HMAC 的默认选择。但两者都属于「快哈希」,都不能直接拿来存口令——需要慢哈希时,请用本页演示的 PBKDF2,或者更现代的 bcrypt / scrypt / Argon2。
常见问题
SHA256加密 和 MD5加密 到底差在哪,我该选哪个?
差在三点:长度(256 位 vs 128 位,十六进制 64 字符 vs 32 字符)、结构强度(SHA-256 的轮函数多了 Σ 与 σ 两组多位移位异或,差分传播更难控制)、现实安全性(MD5 在 2004 年之后可以被主动构造碰撞,公开的一对样本各 128 字节、只差 6 个二进制位却共享摘要 79054025255fb1a26e4bc422aef54eb4;SHA-256 至今没有已知的实用碰撞方法)。默认用 SHA-256;只有当你要对接一个只认 32 位 MD5 的历史系统时,才回过头用 MD5,并且明确它只能防传输损坏、不能防篡改。
SHA-256 能直接用来存用户密码吗?
不能,而且这是最常被问到的一个坑。原因不是它不安全,而是它太快——单轮 SHA-256 一秒能算上亿次,攻击者拿到摘要后可以用字典极快地撞。正确做法是「加随机盐 + 慢哈希」:本页的 PBKDF2 迭代就是一个最小演示,生产环境建议直接用库提供的 bcrypt、scrypt 或 Argon2,它们除了时间成本还会强制吃掉内存,让显卡和专用芯片的优势大幅缩水。
盐到底是什么?需要保密吗?需要多长?
盐是一串随机字节,在算摘要之前拼到口令上。它不需要保密,通常就和摘要放在同一个字段里明文存储;它真正的作用是让「同一个口令在不同记录里算出不同的摘要」,从而让预先算好的彩虹表失效。关键要求是每条记录都不同、并且要足够长(一般 8~16 字节)以防被穷举配对。共用一个固定盐几乎等于没加盐,这也是本页默认盐旁边要特别提示的原因。
为什么反复强调 600000 次这个数字?迭代越多越好吗?
600000 是 OWASP 在 2023 年给出的 PBKDF2-HMAC-SHA256 建议迭代数,它的依据是「让一次校验在现代硬件上耗时约几十毫秒」——既能拖慢攻击者,又不会让用户登录时明显变慢。所以迭代次数不是越大越好,而是要跟着你服务器的性能走:定一个能让单次校验稳定落在可接受区间的值,并在硬件升级后适度上调。本页默认取 10000,是因为纯 JavaScript 实现比原生慢得多,取 600000 会让页面卡住好几秒。
长度扩展攻击听起来很抽象,能说人话吗?
可以。SHA-256 是「压完一块、把结果当下一块的输入」这样链式压下去的,所以最终的摘要其实就是「压完所有块之后的中间状态」。如果服务端用 SHA-256(密钥 || 消息) 当认证标签,攻击者拿到这个标签后,只要知道密钥长度,就能把自己的附加内容接在后面继续压,算出新的合法标签——过程中完全不需要知道密钥。本页复算脚本里走了一遍:公开摘要 35f830db7e101380b440b797462d2e14fa2d70a5cc9c0d63a03a31b1f900158b(10 字节密钥 + 21 字节消息),续算出的 75 字节伪造消息摘要 90bb758aa8d202287349c726320095d3c89d854ea11a3cf4afabf264cf3e1557 会被服务端认可。用 HMAC-SHA256 就不会有这个问题。
bcrypt、scrypt、Argon2 我应该用哪一个?
按「新系统优先 Argon2id、老生态优先 bcrypt」来选就够了。Argon2 是 2015 年密码哈希竞赛的优胜者,能同时调节内存、时间和并行度,抗显卡与 ASIC 能力最强,推荐用 Argon2id 变体;scrypt 是内存硬算法,参数好懂、库也成熟,常见于加密货币与老一些的项目;bcrypt 历史最久、各语言支持最全,靠 cost 参数控制 2cost 轮,注意它把口令截到 72 字节,超长口令会失效。三个都比「单轮 SHA-256」强得多,选哪个都不算错,关键是把成本参数调到当前硬件上约几十毫秒。
为什么不允许我用 Web Crypto 直接算 PBKDF2?
可以用,但它返回的是 Promise,本页为了保证打开就立刻有结果、并且结果可复现,改成用纯 JavaScript 自己实现 SHA-256、HMAC 与 PBKDF2 的完整流程。好处是每一步都能在页面上讲清楚,也能顺手演示长度扩展攻击这类只有拿到中间状态才看得懂的问题。代价是速度比原生慢,所以默认迭代次数取 10000 而不是 600000。
算出来的摘要能反推出原文吗?内容会不会被上传?
不能反推。SHA-256 是单向函数,256 位摘要里也不可能塞回任意长度的原文,唯一可行的方法是对候选原文逐个尝试、比对摘要,这正是字典攻击干的事,也是为什么要给口令加盐并选慢哈希。至于上传:所有计算都在当前页面完成,没有任何网络请求,也不写入浏览器存储。想自己确认,打开开发者工具的 Network 面板,修改原文观察是否有新请求发出即可。
相关工具
- SHA512哈希生成器:同一个 SHA-2 家族的 512 位版本,用 64 位字运算,适合需要更长摘要的场景。
- SHA1哈希生成器:160 位输出、同样已被碰撞攻破,适合用来对照三代摘要的演进。
- 哈希值识别器:手上只有一串十六进制时,先用它按长度与格式判断是哪种摘要。
- JWT解码:HS256 签名的令牌用的就是 HMAC-SHA256,想看清签名段的构成可以对照这一页。
- 在线文本加密工具AES加密:需要的是可逆的保密而不是摘要时,应当用带密钥的对称加密。
- 暴力时间计算器:把字符集、长度和每秒尝试次数代进去,估算摘要被穷举需要多久。
- 密码力量检测:评估一条已有口令被猜中的难易,与加盐迭代是两件不同的事。
- 编码解码:查看全部编码解码工具。