Shell 校验和与核实,校验和(checksum)程序用来从文件中生成相对较小的唯一密钥。我们可以重新计算该密钥,用以检查文件是否发生改变。修改文件可能是有意为之(添加新用户会改变密码文件),也可能是无意而为(从CD-ROM中读取到了错误数据),还可能是恶意行为(插入病毒)。校验和能够让我们核实文件中所包含的数据是否和预期的一样。
备份应用使用校验和检查文件是否被修改,进而作出备份。绝大多数软件发行版都包含了一个校验和文件。即便是像TCP这样强健的协议也无法避免文件在传输途中被修改。因此,我们需要进行测试,确定所接受到的文件是否和原始文件一模一样。
通过比对下载文件和原始文件的校验和,就能够核实接收到的文件是否正确。如果源位置上的原始文件的校验和与目的地上接收文件的校验和相等,就意味着我们接收到的文件没有问题。
有些系统维护了重要文件的校验和。如果恶意软件修改了其中的某些文件,我们就可以通过发生变化的校验和发现这一情况。本章我们将学习如何计算校验和来验证数据完整性。
预备知识
Unix和Linux支持多种校验和程序,但强健性最好且使用最为广泛的校验和算法是MD5和SHA-1。md5sum和sha1sum程序可以对数据应用对应的算法来生成校验和。下面就来看看如何从文件中生成校验和并核实该文件的完整性。
实战演练
使用下列命令计算md5sum:
$ md5sum filename
68b329da9893e34099c7d8ad5cb9c940 filename
如上所示,md5sum
是一个长度为32个字符的十六进制串。
我们可以将输出的校验和重定向到一个文件中,以备后用:
$ md5sum filename > file_sum.md5
工作原理
md5sum
校验和计算的方法如下:
$ md5sum file1 file2 file3 ..
当使用多个文件时,输出中会在每行中包含单个文件的校验和:
[checksum1] file1
[checksum1] file2
[checksum1] file3
可以按照下面的方法用生成的文件核实数据完整性:
$ md5sum -c file_sum.md5
# 这个命令会输出校验和是否匹配的信息
如果需要用所有的.md5
信息来检查所有的文件,可以这样:
$ md5sum -c *.md5
SHA-1是另一种常用的校验和算法。它从给定的输入中生成一个长度为40个字符的十六进制串。用来计算SAH-1校验和的命令是sha1sum
,其用法和md5sum
的类似。只需要把先前讲过的那些命令中的md5sum
改成sha1sum
就行了,记住将输出文件名从file_sum.md5改为file_sum.sha1。
校验和有助于核实下载文件的完整性。ISO镜像文件通常容易出现错误(如下图所示)。一小点错误就会导致ISO无法读取,甚至更糟糕的是会影响所安装的应用程序的正常运行。大多数文件仓库中都包含一个md5或sha1文件,可用于验证下载文件是否正确。
图 2-1
下面是文件的MD5校验和:
3f50877c05121f7fd8544bef2d722824 *ubuntu-16.10-desktop-amd64.iso
e9e9a6c6b3c8c265788f4e726af25994 *ubuntu-16.10-desktop-i386.iso
7d6de832aee348bacc894f0a2ab1170d *ubuntu-16.10-server-amd64.iso
e532cfbc738876b353c7c9943d872606 *ubuntu-16.10-server-i386.iso
补充内容
对于多个文件,校验和同样可以发挥作用。现在就看看如何校验并核实一组文件。
对目录进行校验
校验和是从文件中计算得来的。对目录计算校验和意味着需要对目录中的所有文件以递归的方式进行计算。
md5deep
或sha1deep
命令可以遍历目录树,计算其中所有文件的校验和。你的系统中可能并没有安装这两个程序。可以使用apt-get
或yum
来安装md5deep软件包。该命令的用法如下:
$ md5deep -rl directory_path > directory.md5
# -r使用递归遍历
# -l使用相对路径。默认情况下,md5deep会输出文件的绝对路径
其中,-r
选项允许md5deep
递归遍历子目录。-l
选项允许显示相对路径,不再使用默认的绝对路径。
或者也可以结合find
来递归计算校验和:
$ find directory_path -type f –print0 | xargs -0 md5sum >> directory.md5
用下面的命令进行核实:
$ md5sum -c directory.md5
- md5与SHA-1都是单向散列算法,均无法逆推出原始数据。两者通常用于为特定数据生成唯一的密钥:
$ md5sum file
8503063d5488c3080d4800ff50850dc9 file
$ sha1sum file
1ba02b66e2e557fede8f61b7df282cd0a27b816b file
这种类型的散列算法多用于存储密码。密码只存储其对应散列值。如果需要认证某个用户,则读取该用户提供的密码并转换成散列值,然后与之前存储的散列值进行比对。如果相同,用户则通过认证并授权访问。将密码以明文形式存储是非常冒险的,且存在安全隐患。
尽管应用广泛,md5sum和SHA1已不再安全,因为近年来计算能力的攀升使其变得容易被破解。推荐使用
bcrypt
或sha512sum
这类工具进行加密。更多信息可参看http://codahale.com/how-to-saftyly-store-a-password/。
- shadow-like散列(加盐散列)
让我们看看如何为密码生成shadow-like加盐散列(salted hash)。在Linux中,用户密码是以散列值形式存储在文件/etc/shadow中的。该文件中典型的一行内容类似于下面这样:
test:6fG4eWdUi$ohTKOlEUzNk77.4S8MrYe07NTRV4M3LrJnZP9p.qc1bR5c.EcOruzPXfEu1uloBFUa18ENRH7F70zhodas3cR.:14790:0:99999:7:::
该行中的$6$fG4eWdUi$ohTKOlEUzNk77.4S8MrYe07NTRV4M3LrJnZP9p.qc1bR5c. EcOruzPXfEu1uloBFUa18ENRH7F70zhodas3cR
是密码对应的散列值。
有时候,我们编写的一些脚本需要编辑密码或是添加用户。在这种情况下,我们必须生成shadow密码字符串,向shadow文件中写入类似于上面的文本行。可以使用openssl
来生成shadow密码。
shadow密码通常都是加盐密码(salted password)。所谓的“盐”(SALT)就是一个额外的字符串,起混淆的作用,使加密更加难以破解。盐是由一些随机位组成的,它们作为密钥生成函数的输入之一,产生密码的加盐散列。
关于盐的更多细节信息,请参考维基百科页面http://en.wikipedia.org/wiki/Salt_(cryptography)。
$ openssl passwd -1 -salt SALT_STRING PASSWORD
$1$SALT_STRING$323VkWkSLHuhbt1zkSsUG.
将SALT_STRING
替换为随机字符串并将PASSWORD
替换成你想要使用的密码。