SHA256加密

在本地计算 256 位 SHA-2 摘要,给出 64 位十六进制与摘要 Base64,并用同一段原文演示加盐和 PBKDF2-HMAC-SHA256 迭代次数如何改变一次校验的成本。

演示用的固定盐。真实系统里盐必须每条记录随机生成,并且和摘要一起明文存储。
OWASP 对 PBKDF2-HMAC-SHA256 的建议值是 600000;本页默认 10000,因为浏览器里的纯 JavaScript 实现也要保证即时返回。
SHA-256 摘要(64 个十六进制字符)cf01be2838769ef7aa8ceaef880fa1c24769f632923a23d3aa36d5010864d4e5
32 字节摘要的 Base64zwG+KDh2nveqjOrviA+hwkdp9jKSOiPTqjbVAQhk1OU=
PBKDF2-HMAC-SHA256(盐 liuquan-2026 / 10000 次)5bda76fc7549fdad2c227da353714dade9294ec7d88c0f26a05b72f7d0dc33d2
UTF-8 字节数128
补位后的 512 位分组数3
一次 PBKDF2 的本机耗时—

提示:原文里按 Ctrl + Enter(macOS 用 Cmd + Enter)立刻重算,Enter 留给换行;改盐值或迭代次数会自动连带重算慢哈希。迭代次数调到 100 万时纯 JavaScript 需要数秒,属于正常现象。

常见弱口令的裸 SHA-256 与加盐 SHA-256 对照(前 12 位十六进制)。盐取固定值是为了让表格可复现,真实系统必须一条口令一个随机盐。
#口令裸 SHA-256(前 12 位)加盐后(盐=liuquan-2026,前 12 位)公开彩虹表
11234568d969eef6eca53070b0561bf命中
2password5e884898da286f007d62a90a命中
312345678ef797c8118f08aad47d06d01命中
4qwerty65e84be33532d243b1a8470d命中
512345678915e2b0d3c338ebd569e97272命中
6123455994471abb0155a46e8e361f命中
7123403ac674216f3e4f8734b01f9命中
8111111bcb15f82147901d019704c58命中
912345678bb0cf6eb9b1cf5600a0cff2命中
10dragona9c43be948c5b626d4fd4e00命中
1112312396cae35ce8a923400f4733de命中
12baseballa01edad91c008e57288abb24命中

使用方法

  1. 文本框里已经放好一段示例原文,它是 128 个 UTF-8 字节、26 个汉字;页面打开时结果区显示的就是它的摘要 cf01be2838769ef7aa8ceaef880fa1c24769f632923a23d3aa36d5010864d4e5。换成你的内容后结果自动重算。
  2. 文本框里按 Ctrl + Enter(macOS 用 Cmd + Enter)立刻重算;Enter 留给换行。做接口签名校验时,请求体里的换行和空格同样参与摘要,不能被快捷键吃掉。
  3. 「盐值」默认填 liuquan-2026,只为了方便演示可复现。真实系统里盐是每条记录随机生成的,长度一般 8~16 字节,和摘要一起明文存在数据库里——盐不是秘密,它的作用是让同一个口令在不同记录里算出不同的摘要。
  4. 「PBKDF2 迭代次数」默认 10000,可填 1~1000000。它决定慢哈希要重复多少轮,改这个值只会改变第三张卡片里的 PBKDF2 结果,不影响前面那张单轮 SHA-256 摘要。
  5. 点「复制摘要」默认复制单轮 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。结果如下:

同一条原文换盐或换迭代次数,结果立刻分叉,这三个值都可以在页面上直接复现:

拿公开测试向量交叉验证: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 的结果
MD5128 位3216900150983cd24fb0d6963f7d28e17f72
SHA-1160 位4020a9993e364706816aba3e25717850c26c9cd0d89d
SHA-256(本页)256 位6432ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
SHA-512512 位12864ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a…

第二张表把「裸哈希 / 加盐 / 加盐再迭代」三种配置放在一起,看它们分别挡得住什么。倍数一栏是相对单轮无盐哈希的计算成本:

配置彩虹表能否直接命中相对计算成本说明
裸 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 生日界拉开了天壤之别。

结果边界与取舍说明

常见问题

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 面板,修改原文观察是否有新请求发出即可。

相关工具