当我们在网上下载一个软件包时,一般会附带一个hash文件,这个里面就保存了通过软件包计算的哈希值,官方名字叫散列值,用来让使用者确认软件包有没有被篡改的,而计算这个散列值就是由单向散列函数生成的。单向散列函数有一个输入和一个输出,输入成为消息,输出就成为散列值。
也被称为消息摘要函数(message digest function),哈希函数和杂凑函数。
也被称为原像(pre-image)。
也称为消息摘要(message digest)或者指纹(fingerprint)。
单向散列函数可以处理任意长度的消息,无论消息多长,产生的散列值都是固定的。
计算散列值应该随着消息长度的增加线性增加,而不能是指数增加。如果不能在可接受的计算时间内完成就没有意义。
哪怕是消息中的其中一个字节发生改变,也必须产生完全不同的散列值,这种不同的消息产生相同的散列值的情况称为碰撞。抗碰撞性是衡量一个单向散列函数安全的重要指标。
表示由散列值无法计算出消息的性质。就如同砸碎玻璃很简单,但是把玻璃碎片拼成玻璃很难是一个道理。
MD4和MD5分别是在1990和1991年设计出来的,都能够产生128比特(16字节)的散列值,由于这两个函数的强抗碰撞性都已经被攻破,已经不再安全,所以,现在已经不推荐使用了。
SHA-1是由NIST设计的一种160比特(20字节)的散列值的单向散列函数。SHA-1已经在2005年被攻破,现在已经不推荐使用了。
SHA-256,SHA-384和SHA-512统称为SHA-2。SHA-2包含六种版本,分别是SHA-224,SHA-256,SHA-512/224,SHA-512/256,SHA-384和SHA-512,它们都是SHA-256和SHA-512的变种。输出的散列值的长度分别为224(28字节),256(32字节),224(28字节),256(32字节),384(48字节)和512(64字节)比特。
在2005年SHA-1被攻破的背景下,NIST开始着手研究SHA-3,也是和AES一样,通过公开竞选的方式进行标准化,SHA-3的选拔于2012年完成,由名为Keccak的算法胜出,成为SHA-3。
NIST规定,参与竞选的算法必须和AES一样,能够让所有人自由免费的使用SHA-3算法。
注意:
由于SHA-2还没有被攻破,所以SHA-2和SHA-3目前都是安全的。
openssl通过dgst选项来进行单向散列函数操作的,通过openssl dgst -list可以列出当前openssl支持的单向单列函数,例如:
- [root@ sha1]#openssl dgst -list
- Supported digests:
- -blake2b512 -blake2s256 -md4
- -md5 -md5-sha1 -mdc2
- -ripemd -ripemd160 -rmd160
- -sha1 -sha224 -sha256
- -sha3-224 -sha3-256 -sha3-384
- -sha3-512 -sha384 -sha512
- -sha512-224 -sha512-256 -shake128
- -shake256 -sm3 -ssl3-md5
- -ssl3-sha1 -whirlpool
MD4:
infile内容:
hello, md4
openssl dgst -md4 infile
MD4(infile)= 4462e317a5ebbdb5f0d3774c1c45c103
从stdin获取内容:
echo -n "hello, md4" | openssl dgst -md4
(stdin)= 4462e317a5ebbdb5f0d3774c1c45c103
MD5:
从stdin获取内容:
echo -n "hello, md5" | openssl dgst -md5
(stdin)= 33b3bc8e05b4fcc16bd531dd9adac166
注意,MD4和MD5的散列值是16字节,以上都是以16进制显示的"33b3bc8e05b4fcc16bd531dd9adac166"其实是0x33 0xb3 0xbc 0x8e 0x05 0xb4 0xfc......0xac。
echo -n 'hello,sha1' | openssl dgst -sha1
(stdin)= 73eb2c728f810753c9537ab9b876c9c0305255f5
同样,SHA-1的输出是20字节,上面是以16进制显示的。
SHA256:
echo -n "hello,sha2" | openssl dgst -sha256
(stdin)= 2124f3c215a468c4cef31fb974b7093baccad0180a415e34031f551372ff2d4cSHA-384:
echo -n "hello,sha384" | openssl dgst -sha384
(stdin)= e15397fd702d3535b063ce4261a9bb6a6f8c6086b5d7af48a843c90bb25419c6df8206c8655cd3e1db20b4668c7c2433SHA-512:
echo -n "hello,sha512" | openssl dgst -sha512
(stdin)= 30fc79c63ebe7cbd1d6d5d2b5e4759bb13415b5e5284973b9fd5bd26a8f5beea3d277d549234e1d4c13c7f5027240eb70c92f831c3c157f87274a2802d48e379
SHA3-256:
echo -n "hello,sha3-256" | openssl dgst -sha3-256
(stdin)= 125419436802bc6d47c8100b6fd130492a404d48a935299e367da1bbdfae22d6
openssl除了支持sha3-256,还支持sha3-224,sha3-384和sha3-512。
单向散列函数能够很容易的根据消息计算出散列值,但是却很难根据散列值计算出消息的内容,所以,单向散列函数通常用于确定一个消息是否被篡改。单向散列函数有MD4和MD5,由于它们已经被攻破,所以现在一般不建议使用了,SHA-1也于2005年被攻破,所以也不建议使用了,SHA-2和SHA-3由于目前还未被攻破,所以认为是安全的,可以使用。