哈希是回不去的
加密只要有密钥就能还原原文,哈希没有这样的密钥。它把任意长度的输入压成一个定长的值,是条单行道,从结果里算不出原文。
所以哈希只回答一个问题:这两样东西是不是一样。下载的文件和发布方公布的值一不一致,刚输入的密码和存着的那个一不一致。要是某个值需要先藏起来、以后还要取出来看,那该用加密,不是哈希。
该选哪种算法
- MD5 — 1991 年的设计。造出两段不同却哈希相同的输入,笔记本几秒就够。它还活着,只因为发布方仍在贴 MD5 校验值,所以还得拿它来核对。
- SHA-1 — 2017 年公开过两份真实碰撞的 PDF,新项目没有理由选它。
- SHA-256 — 当下的默认选择,证书、签名和区块链都在这一档。
- SHA-384 与 SHA-512 — 基于 64 位运算,在 64 位机器上有时比 SHA-256 还快。需要更长的摘要时选它们。
只是做完整性校验,SHA-256 就够了。如果发布方只给了 MD5,那就用它核对,但文件来源是否可信,要另外判断。
密码光靠这个不够
把密码存成 SHA-256 比明文好,但依然危险。哈希函数天生就是为快而设计的,攻击者每秒能试上十亿次,常见密码早就被做成了表。
密码请用故意做慢的函数:bcrypt、scrypt 或 Argon2。它们的计算成本可调,还会为每个用户自动加不同的盐。别自己实现,用所在语言现成的库就行。
同一个文件,值却不一样
这个工具会把输入转成 UTF-8 字节再算哈希。和命令行工具对不上时,差别几乎都藏在看不见的地方。
- 换行符 — Windows 的
\r\n和 Unix 的\n是不同的字节。 - 结尾多的换行 —
echo默认会加一个,试试echo -n或改用printf。 - BOM — 有些编辑器会在文件开头塞 3 个字节。