跳转至

文件哈希比对

什么时候用得上

文件不经过网络发出去的时候,收到的人没有办法确认取得的是不是完整的那一份。

  • U 盘或存储卡带过去。中途换过手、放在包里压到、拔的时候还在写入,这些都会让文件坏掉,而坏掉的文件打得开的概率比想象中高,只是内容少一段
  • 托人带过去。你要确认的是送到的那份跟你手上的一样
  • 下载回来的安装包。Tor Browser、Tails 这类软件都会公布哈希,比对过再安装
  • 两台设备之间搬完东西。用 QR code 影格串流或别的方式搬完,比一次确认拼回来的内容完整

断网的时候这件事更重要,见网络中断时的准备与应对。实体递送在那种情况下是主要的渠道,而收件的人没有第二次机会回头要一份。

相符代表什么

两份文件算出同一个 SHA-256,内容就是一模一样的,一个字节都不差。要刻意做出两份内容不同、SHA-256 相同的文件,目前公开的研究做不到。

不相符代表内容有差异。差异的来源可能是传输中断、存储介质坏了,也可能是有人动过。哈希本身分不出是哪一种。

这个做法的前提

比对的价值全部建立在一件事上:你手上那串哈希,确实是对方算出来的那一串。

能换掉文件的人,通常也能换掉跟文件放在一起的哈希。把 hash.txt 跟文件一起放进 U 盘,两个一起被换掉,比对照样相符。

所以哈希要走跟文件不同的一条路:当面念、打电话、用已经确认过对方身份的通信软件传。这跟断网情境页里「备用渠道要走不同的路」是同一个道理,失效条件不同才有意义。

六十四个字念起来很长。实务上念前八个字与后八个字就足以挡掉意外损坏与随手替换,要防的是有能力针对你做前置计算的对手时,才需要整串核对。

加密与哈希比对是两件事

本机文件加密防的是内容被看到,哈希比对确认的是内容没有变。两件事互相独立,加密过的文件一样可以算哈希,而且应该对加密后的文件算,那才是实际被搬运的东西。

为什么是 SHA-256

MD5SHA-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 的段落抽出来,再看你的文件算出的值在不在里面。大小写都认得。

离线可用

跟这一区其他工具一样,程序存进设备之后没有网络也能用。实体递送的场合本来就常常没有网络,要把这一页带着走,见离线阅读

文件在你的浏览器里计算,没有上传,也没有写进设备的任何存储空间。关掉页面就没了。