通常为了防止文件的内容被修改,如一个文件号称是包含了补丁的文件,却被人加入了木马;同时也可以用来保证文件的完整性,防止文件被损坏。
当然,一些 hash 算法可能会被破解,所以一些网站则提供了多种完整性校验方法。
MD5
计算出下载文件的 MD5 哈希值,然后与发布者提供的 MD5 哈希值比较,通过判断是否一致来断定文件在发布者发布之后有没有被篡改过。
使用的假设是,同一个文件产生的 MD5 哈希值是唯一的,但这点已经有办法通过对文件进行少量的修改,让文件的 MD5 后的哈希值保持一致,虽然操作起来有点难,但是确实有风险。
$ md5sum file-name # 计算MD5哈希值
da9741366673b5066e74f5307c7d08d7 file-name
$ md5sum file-name > file-name.md5 # 将计算的哈希值保存到文件,可含多个
$ md5sum -c file-name.md5 # 校验文件是否被修改
file-name: OK # 失败为 file-name: FAILED ...
SHA
原理同 MD5 一样,相比 MD5 来说更安全一些,而且在在 HASH 求值方面,MD5 退出的舞台将由 SHAn 占据。SHA 家族有五个算法:SHA-1、SHA-224、SHA-256、SHA-384 和 SHA-512,后四种有时候称为 SHA2 ,分别对应 linux 中的 sha…sum 命令。
$ sha1sum file-name # 计算SHA1哈希值
b14cb291f379140f1466381be80466c6722e4b1a file-name
$ sha1sum file-name > file-name.sha1 # 将计算的哈希值保存到文件,可含多个
$ sha1sum -c file-name.sha1 # 校验文件是否被修改
file-name: OK # 失败为 file-name: FAILED ...
PGP
实际上原理很简单,也就是使用非对称加密。首先生成唯一的密钥对,包括了公钥和私钥,然后执行如下步骤。
发布者:
1. 将密钥对中的公钥发布到公钥服务器;
2. 通过私钥对需要发布的文件进行签名,得到签名文件;
3. 将文件和用私钥生成的签名一起发布;
下载者:
1. 下载发布者发布的文件和签名;
2. 使用 PGP 获取发布者发布到服务器的公钥;
3. 使用公钥校验文件签名。
关于 GnuGP 的使用,详细可参考 MySQL 的内容 2.1.3.2 Signature Checking Using GnuPG 。
$ gpg --import pubkey.asc # 从官网上下载公钥,然后导入
$ gpg --keyserver keyserver.ubuntu.com --recv-keys 8D253E8A # 或者可以直接从服务器导入
$ gpg --verify downloaded-file-sign.asc # 如果没有导入公钥,则会提示No public key
到现在为止,我们可以确认该文件在上传之后没有被修改过。
但是,需要注意的是这个是未受信任的签名认证,因为这个公钥谁都可以发布上去的。如果确实需要进一步认证,可能还要联系下真正的发布者,确认这个密钥的指纹 (fingerprint),这也就是为什么在上述验证时可能会出现 WARNING 。
但是通常来说,通过用户名和邮箱就可以基本确定的。当确认信任该公钥后,可以通过如下的子命令设置信任该公钥,这样就不会再出现上面的 WARNING 。
$ gpg --edit-key 'user-id' + sign