把“blue”改成“Blue”,就会得到一串看似毫无关联的新数字。
句子几乎没变,文件的指纹却大变样。这正是密码学哈希的吸引力:你可以比较一个简短结果,而不用亲自检查每个字节。但比较背后藏着一个前提:你得有理由相信,用来对照的那个指纹本身是可信的。
校验值可以确认是否匹配,却不能替发送者作自我介绍。
什么是文件指纹
SHA-256 接收字节,生成 256 位的摘要,通常写成 64 个十六进制字符。相同字节会得到相同结果。文件名不是文件内容的一部分,所以仅仅重命名不会改变内容哈希;修改实际存储的字节,哪怕肉眼看不出来,通常也会改变它。
摘要不是可以展开还原原文件的压缩副本。输入的可能性多于有限的输出空间,因此理论上一定存在碰撞,也就是不同输入得到相同摘要。SHA-256 的设计目标之一,是让寻找这类碰撞在计算上不可行。哈希一致,是内容一致的强有力实用证据,却不是所有可能输入都一一对应的数学证明。
一个水壶、一个大写字母和一点空白
我们把无害的句子“The kettle is blue.”连同结尾的一个换行符保存下来,文件共 20 字节。然后制作四个版本:把 b 改成 B、在换行前加一个空格、改用回车加换行的行尾,以及删去最后的换行。每个版本都实际写入磁盘,再读回来。
四份修改后的文件都产生了不同的 SHA-256 摘要。大小写变化实际上只翻转了输入中的一个比特,却让摘要的 256 位中有 120 位不同。增加空格对应 129 位变化,替换行尾对应 128 位,删除换行对应 125 位。这些都是针对这几份具体文件测得的结果。

对哈希来说,空白也是信息
读者可能认为两种行尾格式下的句子完全一样,但按字节比较时并非如此。文本编辑器、导出工具和传输过程,可能改变行尾或编码,却不带来明显的视觉差异。校验失败时,先确认比较的是同一个版本、同一份文件,而不是复制出来的文字或重新生成的文件。
不要把摘要中有多少位不同,当成修改量的评分。多一个空格,并没有在人类关心的意义上比一个大写字母“改得更多”。哈希输出本来就不保留这种相似关系。图案说明的是对变化的敏感性,不是用来衡量语义差别或损害程度的尺子。

错误文件,也可以带着匹配的校验值
假设文件和预期校验值都来自同一个不可信的地方。有人替换文件后,为新文件重新计算校验值,你的比较仍然会通过。我们用那个无害的大写版本演示了这一点:把它与自己的摘要配对,检查当然成功。这不需要破解密码学算法,变化的是作为依据的参考值。
下载文件时,应从你有充分理由信任的来源取得预期摘要,用相同算法计算,并比较全部 64 个十六进制字符。放在下载链接旁的摘要可以帮助发现意外损坏。但若同一个受侵入的来源能够同时替换文件和摘要,仅靠这两样东西,就无法证明发布者身份。

签名补上的是另一类证据
数字签名可以把文件与签名密钥联系起来,并揭示签名之后的修改。但紧接着必须问:用于验证的密钥,真的属于你预期的发布者吗?在一把陌生密钥下验证成功,仍然不够。应遵循发布者说明的验证流程,或采用可信的分发渠道,而不是临时拼凑一条信任关系。
即便签名确实可信,文件也不保证无害、没有缺陷、足够新,或适合你的设备。完整性、真实性和安全性相关,却是不同的检查。校验工具不是恶意软件扫描器;本次文本实验没有测试签名、签名密钥、可执行文件,也没有测试任何下载服务的安全。
让比较始终带着背景信息
当文件需要在复制、传输或归档后保持不变时,校验值特别有用。把算法、准确的文件版本和可信参考摘要一起记录下来。以后某份副本若不一致,先停下来调查,不要强行让结果吻合,也别立刻断定发生了攻击。
如果没有可信参考,新计算的哈希仍然能作为以后比较的基线。但它不能倒过来证明当前文件最初来自哪里。分清这点,工具反而更好用:你知道它消除了哪一种不确定性,也知道还有哪些问题需要另找证据。
