文件哈希比对¶
什么时候用得上¶
文件不经过网络发出去的时候,收到的人没有办法确认取得的是不是完整的那一份。
- U 盘或存储卡带过去。中途换过手、放在包里压到、拔的时候还在写入,这些都会让文件坏掉,而坏掉的文件打得开的概率比想象中高,只是内容少一段
- 托人带过去。你要确认的是送到的那份跟你手上的一样
- 下载回来的安装包。Tor Browser、Tails 这类软件都会公布哈希,比对过再安装
- 两台设备之间搬完东西。用 QR code 影格串流或别的方式搬完,比一次确认拼回来的内容完整
断网的时候这件事更重要,见网络中断时的准备与应对。实体递送在那种情况下是主要的渠道,而收件的人没有第二次机会回头要一份。
相符代表什么¶
两份文件算出同一个 SHA-256,内容就是一模一样的,一个字节都不差。要刻意做出两份内容不同、SHA-256 相同的文件,目前公开的研究做不到。
不相符代表内容有差异。差异的来源可能是传输中断、存储介质坏了,也可能是有人动过。哈希本身分不出是哪一种。
这个做法的前提¶
比对的价值全部建立在一件事上:你手上那串哈希,确实是对方算出来的那一串。
能换掉文件的人,通常也能换掉跟文件放在一起的哈希。把 hash.txt 跟文件一起放进 U 盘,两个一起被换掉,比对照样相符。
所以哈希要走跟文件不同的一条路:当面念、打电话、用已经确认过对方身份的通信软件传。这跟断网情境页里「备用渠道要走不同的路」是同一个道理,失效条件不同才有意义。
六十四个字念起来很长。实务上念前八个字与后八个字就足以挡掉意外损坏与随手替换,要防的是有能力针对你做前置计算的对手时,才需要整串核对。
加密与哈希比对是两件事¶
本机文件加密防的是内容被看到,哈希比对确认的是内容没有变。两件事互相独立,加密过的文件一样可以算哈希,而且应该对加密后的文件算,那才是实际被搬运的东西。
为什么是 SHA-256¶
MD5 与 SHA-1 都已经有公开的碰撞范例,可以做出两份不同的文件算出同一个值,拿来确认文件有没有被动过已经不安全。这一页只做 SHA-256。
软件发布方公布的多半也是 SHA-256。看到 MD5 的哈希时,多半代表那份发布信息已经很旧。
几 GB 的文件也算得动¶
浏览器内建的哈希接口要一次读进整份文件,手机上读一份几 GB 的视频会直接失败,而失败的样子是标签页没有反应。
这一页自己实作 SHA-256,一块一块读进来算,内存用量固定,过程中会显示进度。自己实作的风险是算错了画面看起来一样正常,所以 tools/test_hash.mjs 用三组互相独立的来源交叉验证:NIST 公布的标准测试向量、Node 内建的 crypto 模块,以及同一份数据切成不同大小喂进去必须算出同一个值。
不用这一页也做得到¶
命令行本来就有,而且不必信任任何网页:
- Linux 与多数 BSD:
sha256sum <文件> - macOS:
shasum -a 256 <文件> - Windows PowerShell:
Get-FileHash <文件>
三个命令算出来的值跟这一页一样。这一页存在的理由是手上只有浏览器的时候,例如借来的电脑、平板、或是不熟悉命令行的伙伴。
贴什么格式都认得¶
对方给的哈希可能是单独一串字、sha256sum 的输出(哈希、两个空格、文件名),也可能是一整份清单。整段贴进来就好,工具会把里面所有 SHA-256 的段落抽出来,再看你的文件算出的值在不在里面。大小写都认得。
离线可用¶
跟这一区其他工具一样,程序存进设备之后没有网络也能用。实体递送的场合本来就常常没有网络,要把这一页带着走,见离线阅读。
文件在你的浏览器里计算,没有上传,也没有写进设备的任何存储空间。关掉页面就没了。