只改一点,摘要会怎样变?
哈希算法把一条消息算成固定长度的数字,叫“摘要”。同一条消息用同一种算法,总会得到同一份摘要。
这里准备两份几乎相同的输入,只改其中一位,再分别完整计算。跟着画面看:开始时差别很小,后面的许多结果也会不同。
摘要不是能解回原文的密文。 不同消息也可能得到同一摘要。这次实验让你看清输入怎样影响结果,并不能单独证明一种算法安全。
保持同一输入,再只动一位
- 保持文字不变,关闭翻转:两份结果是否完全相同?
- 再只翻转一位,比较前后哪些位置不同,不必逐个抄数字。
- 载入较长的示例,跟住第一块怎样把状态交给下一块。需要验算时,再展开计算详情。
真正执行了哪些步骤?
进一步操作与数值核对
- 在“自己试试”中输入文字,选择一个 UTF-8 字节及其
b0…b7。翻转直接作用于字节,所以对照字节未必仍是有效文字;模型不会偷偷替换成 Unicode 替代字符。 - 关闭一位翻转,两次计算在每个位置都一致。开启后,查看同一块的输入状态、任意一轮之后的状态,以及加回后的链值。
- “压缩与加回进度”支持方向键;“上一步”“下一步”提供 44px 以上目标。0 是块输入,1–64 是已完成的轮数,65 是 feed-forward 加回。不是把工作状态直接当作摘要。
- 载入 56 字节双块示例,选择第二块。第二块的输入必须等于第一块输出,不会重新使用最初的常量。
- 输入
é与é,或中文、表情。看 UTF-8 字节数而不是屏幕字数。本篇不做 Unicode 规范化。空消息也有有效摘要,但没有可翻转的输入位。 - 展开计算详情,读取完整的两个摘要及当前轮的 Σ、Ch、Maj 数值。“重置全部”恢复
abc、第一字节、b0、翻转开启、第一块、加回步骤,并关闭详情。
界面限定最多 1024 个 UTF-8 字节,用于让完整轨迹保持轻量。这是教学上限,不是 SHA-256 标准的消息上限。模型只接收整字节消息;标准也允许非整字节位串。图中时间为教学播放时间,不是硬件耗时。
想核对技术细节?
把一条消息交给哈希算法,它会算出一串固定长度的数字,叫“摘要”。同一输入总得出同一摘要;只改一个小地方,也可能让很多输出位改变。先看这次“一位改变”的对照,再展开里面的计算。摘要不是能把原文解回来的密文。
本篇完整实现 SHA-256,而不是把文字映射成好看的随机纹理。默认消息 abc 的 UTF-8 字节是 61 62 63,均以十六进制表示。跟住第一个字节 a 的最低位 b0:它原本为 1,按大端顺序装入消息字后,成为 W[0] = 61626380 的位 24。位编号从最低位的零开始数。
起初能找到这一位的明确位置;经过旋转、按位布尔运算和带进位的加法后,不能再说某个输出格子“就是原来那一位”。要观察影响,我们复制同一份输入,只将第一字节异或 01,然后从头计算两次。其他输入位、初始状态、算法和每轮常量完全一致。
默认对照的字节是 60 62 63。最终两个摘要有 112/256 位不同。金色短线表示同一位置的两个计算结果不相等;它不是粒子路径,也不是随机着色。差异数量在中间轮次会回落,不保证逐轮增长,更不保证每个输入都恰好改变一半。
哈希摘要固定为 256 位。不同消息必然可能映射到相同摘要,这叫碰撞;“碰撞存在”与“能够找到碰撞”是不同问题。这次对照没有寻找碰撞,也不能证明密码学安全性。
填充不是把原文加密
将文字转成 UTF-8 属于编码。SHA-256 本身接受位串,不负责选择文字编码。模型按字节处理:先加入 80,其最高位为新增的一位 1,其余七位为零;继续补零,最后附上 64 位大端原始消息长度,使总长度为 512 位的整数倍。
长度字段记录 24,而不是填充后的 512。56 字节消息已有 448 位,放入新增 1 和 64 位长度字段后装不下一个块,因此需要两块。每个块拆成 16 个 32 位大端字。
哈希不是可逆的文字编码,也不是使用密钥加密后等待解密的密文。摘要不保存一份可以直接还原的原文副本。
消息扩展中的旋转与加法
前 16 个消息字来自输入块,后续 48 个按递推式生成。下面的加法均模 2³²,也就是只保留结果低 32 位。
ROTR 是循环右旋,移出低端的位回到高端;SHR 是逻辑右移,高端补零。默认消息的 W[16] 恰好等于 W[0],所以这一步还能看到被跟踪位;这不是所有消息或后续扩展字的通性。
一轮怎样改变八个工作字?
八个工作字记作 a 到 h。Ch 根据 x 的每一位选择 y 或 z;Maj 取三个对应位的多数值。
大 Σ₀ 的右旋位数为 2、13、22;大 Σ₁ 为 6、11、25,三个结果以异或合并,均不包含逻辑右移。K[t] 是标准规定的固定轮常量。
新的 a 是 T1 + T2,新的 e 是 d + T1;其余六个字依次传递原来的 a、b、c、e、f、g。全部计算使用旧状态同时生成新状态,不会把刚更新的 a 又拿去生成同一轮的其他字。
为什么还要加回块输入?
每块进行 64 轮,然后将八个工作字分别加回进入该块的八个链值。第一块输入是标准初始常量;之后每块使用前块的输出。这里的压缩是固定长度链值更新,不是可逆的文件压缩。
直到最后一块完成,才按 H0 到 H7 的顺序串接为 256 位摘要。十六进制每字符表示四位,因此常见写法有 64 个字符。
本篇对照了 NIST 的单块、双块摘要和公开中间轮状态;另用 WebCrypto 与 Node crypto 独立计算空消息、Unicode、填充边界、多块消息和一位扰动。通过这些检查不等同于 CAVP 认证。影片也没有证明抗碰撞、抗原像或任何特定用途的安全性。
资料:NIST FIPS 180-4、NIST SHA-256 中间值示例、NIST Secure Hashing 验证说明。