正文

散列函数又称散列算法、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。简单地说,往散列函数里丢入任意大小的字符串或文件,都会得到一个散列值,例如

1
2
3
4
string         SHA-256
123456 --> 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
123457 --> 54b688a517f7654563a6c64d945a3670880a4c602ec67a065bbebbcd2b22edd5
123458 --> e6757959da8eff84c42d4df125b44eb40143dff452afd56aea5cfa058f245028

得到的同一种散列值,都是等长且唯一确定的,如这三项所示,哪怕只有最后一位不一样,计算出的 SHA-256 都会完全不同。最重要的是,散列函数是一个“单向”操作,目前来说,仅知道散列值,是绝对无法反向计算出原始数据的(不考虑彩虹表),所以散列函数的用处有

加密数据

严格来讲,哈希其实并不是加密,它不具备可解密性,前面讲过,无法从哈希值倒推原始值,如各种非对称加密算法,用公钥加密的内容可以用私钥解密,才是加密。我们的各个账号的密码,会以哈希值的形式储存在服务商那里,登录时比对哈希值即可。不储存原始密码,一定程度上防止因数据库泄露造成其他相同密码的账号被盗用(即撞库)

错误校正

可以检测数据在传输时发生的错误甚至在一定范围内纠正错误数据,这样的散列函数被称作错误校正编码,例如里德-所罗门码(RS codes),是一种前向错误更正的信道编码,可以计算出错误位置并自动纠正,主要用于光盘、数据传输、广播和二维码(这大概就是二维码破损一部分却仍能扫出来的原因)

保证数据的完整性

该如何检测我们下载的文件是否是完整的,并未在下载时出错或经人篡改呢?计算文件哈希值并与文件来源提供的哈希值对比即可
MD5SHA-1 因为设计缺陷,分别在2004年和2017年正式被碰撞破解,浏览器基本已禁用 SHA-1 证书,转而采用更安全的 SHA-2。而 Windows 系统内置了一个叫 certutil 的命令行程序,我们可以借用它来完成哈希计算,我会的主要有三种方法,依次进阶

CMD 命令行单次计算

按一下 Win 徽标键,输入 cmd 进入命令提示符,键入

1
2
3
4
5
certutil -hashfile D:\hashfile\Aegisub-3.2.2-32.exe SHA512
# 便会输出
SHA512 的 D:\hashfile\Aegisub-3.2.2-32.exe 哈希:
6d72a5c1da9cede3cf4092edf77c63b443e47b2cbba2b638702b71437fe0dc93eddf57d407616593d6f40adc33af99269f9a43e9017ee25cc9fddf35ac9968b7
CertUtil: -hashfile 命令成功完成。

缺点是每次都打命令,又麻烦又慢

批处理文件拖动计算

新建一个文本文档,后缀改为 bat ,右键–>编辑(E),输入

1
2
3
4
@echo off
set input=%1
certutil -hashfile %input% SHA512
pause

保存,然后把文件拖上去,便会显示输出

1
2
3
4
SHA512 的 D:\hashfile\Aegisub-3.2.2-32.exe 哈希:
6d72a5c1da9cede3cf4092edf77c63b443e47b2cbba2b638702b71437fe0dc93eddf57d407616593d6f40adc33af99269f9a43e9017ee25cc9fddf35ac9968b7
CertUtil: -hashfile 命令成功完成。
请按任意键继续. . .

想计算其他函数只需要把 SHA512 改为对应的函数就可以了,或者把这行复制一下再改,可同时输出多个结果

批量计算某类型文件

还是创建一个 bat ,输入

1
2
for %%f in (*.jpg *.mkv) do (certutil -hashfile "%%f" SHA256 | find /v "hash")
pause

双击运行,会自动计算文件夹里所有 .jpg.mkv 扩展名文件的哈希值

其他工具

1
2
3
4
5
6
7
# PowerShell
PS C:\Users\Public> Get-FileHash C:\Users\Public\Downloads\Aegisub-3.2.2-32.exe -Algorithm MD5 | Format-List

Algorithm : MD5
Hash : 7717D85EBB15EE3A2B30E3271068FA0F
Path : C:\Users\Public\Downloads\Aegisub-3.2.2-32.exe
# 不指定 -Algorithm 则默认 SHA256
1
2
3
4
5
6
7
8
9
# Git Bash
$ md5sum Aegisub-3.2.2-32.exe
7717d85ebb15ee3a2b30e3271068fa0f *Aegisub-3.2.2-32.exe
# 如果同目录下有附带的 SUM 文件
$ cat Aegisub-3.2.2.md5sum
7717d85ebb15ee3a2b30e3271068fa0f *Aegisub-3.2.2-32.exe
# 只需要使用 -c 参数便会自动计算匹配
$ md5sum -c Aegisub-3.2.2.md5sum
Aegisub-3.2.2-32.exe: OK

后记

写了一些奇怪的东西,其实也不用太在意,Windows 平台多半使用数字证书验证