密码技术 (3) - 单向散列函数

一. 前言

        当我们在网上下载一个软件包时,一般会附带一个hash文件,这个里面就保存了通过软件包计算的哈希值,官方名字叫散列值,用来让使用者确认软件包有没有被篡改的,而计算这个散列值就是由单向散列函数生成的。单向散列函数有一个输入和一个输出,输入成为消息,输出就成为散列值

二. 术语

1. 单向散列函数

        也被称为消息摘要函数(message digest function),哈希函数杂凑函数

2. 消息

        也被称为原像(pre-image)。

3. 散列值

        也称为消息摘要(message digest)或者指纹(fingerprint)。

三. 单向散列函数的性质

1. 根据任意长度的消息计算出固定长度的散列值

        单向散列函数可以处理任意长度的消息,无论消息多长,产生的散列值都是固定的。

2. 能够快速计算出散列值

        计算散列值应该随着消息长度的增加线性增加,而不能是指数增加。如果不能在可接受的计算时间内完成就没有意义。

3. 消息不同散列值不同

        哪怕是消息中的其中一个字节发生改变,也必须产生完全不同的散列值,这种不同的消息产生相同的散列值的情况称为碰撞。抗碰撞性是衡量一个单向散列函数安全的重要指标。

4. 具备单向性

        表示由散列值无法计算出消息的性质。就如同砸碎玻璃很简单,但是把玻璃碎片拼成玻璃很难是一个道理。

四. 单向散列函数的种类

1. MD4,MD5

        MD4和MD5分别是在1990和1991年设计出来的,都能够产生128比特(16字节)的散列值,由于这两个函数的强抗碰撞性都已经被攻破,已经不再安全,所以,现在已经不推荐使用了。

2. SHA-1,SHA-256,SHA-384,SHA-512

        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字节)比特。

3. SHA-3

        在2005年SHA-1被攻破的背景下,NIST开始着手研究SHA-3,也是和AES一样,通过公开竞选的方式进行标准化,SHA-3的选拔于2012年完成,由名为Keccak的算法胜出,成为SHA-3。

        NIST规定,参与竞选的算法必须和AES一样,能够让所有人自由免费的使用SHA-3算法。

注意:

        由于SHA-2还没有被攻破,所以SHA-2和SHA-3目前都是安全的。

五. openssl实践

        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    
1. MD4,MD5

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。

2. SHA-1

echo -n 'hello,sha1' | openssl dgst -sha1
(stdin)= 73eb2c728f810753c9537ab9b876c9c0305255f5

        同样,SHA-1的输出是20字节,上面是以16进制显示的。

3. SHA-2

SHA256:

echo -n "hello,sha2" | openssl dgst -sha256
(stdin)= 2124f3c215a468c4cef31fb974b7093baccad0180a415e34031f551372ff2d4c

SHA-384:

echo -n "hello,sha384" | openssl dgst -sha384
(stdin)= e15397fd702d3535b063ce4261a9bb6a6f8c6086b5d7af48a843c90bb25419c6df8206c8655cd3e1db20b4668c7c2433

SHA-512:

echo -n "hello,sha512" | openssl dgst -sha512
(stdin)= 30fc79c63ebe7cbd1d6d5d2b5e4759bb13415b5e5284973b9fd5bd26a8f5beea3d277d549234e1d4c13c7f5027240eb70c92f831c3c157f87274a2802d48e379

3. SHA-3

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由于目前还未被攻破,所以认为是安全的,可以使用。

你可能感兴趣的:(密码技术,密码技术)