在刑事侦查中,侦查员会用到指纹,在计算机中,使用单向散列函数就可以获取消息的指纹,通过对比指纹,就能够知道两条消息是否一致
什么是单向散列函数
单向散列函数有一个输入和一个输出,其中输入称为消息,输出称为散列值,单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检查消息的完整性。
这里的消息可以是文字、图像文件或者声音文件。单向散列函数不需要知道消息实际代表的含义,任何消息,单向散列函数都会将它作为单纯的比特序列来处理,即根据比特序列计算出散列值。
散列值长度和消息的长度无关,1比特、100GB,单向散列函数都会计算出固定长度的散列值。 SHA-256所计算出的散列值的长度永远是256比特(32字节)
单向散列函数的性质
两个不同的消息产生同一个散列值的情况称为碰撞,如果要将单向散列函数用于完整性的检查,则需要确保在事实上不可能被人为地发现碰撞。
难以发现碰撞的性质称为抗碰撞性,密码技术中所使用的单向散列函数,都需要具备抗碰撞性。
单向散列函数必须确保要找到和该条消息具有相同散列值的另外一条消息是非常困难的。这一性质称为弱抗碰撞性。单向散列函数都必须具备弱抗碰撞性。
要找到散列值相同的两条不同的消息使非常困难的 这一性质称为强抗碰撞性,在这里,散列值可以是任意值。单向散列函数都必须具备强抗碰撞性。
单向散列函数必须具备单向性,单向散列函数并不是一种加密,因此无法通过解密将散列值还原为原来的消息。
单向散列函数也称为消息摘要函数、哈希函数、杂凑函数
单向散列函数的实际应用
检测软件是否被篡改
很多软件都会通过单向散列函数计算出的散列值公布在自己的官方网站上,用户在下载到软件之后,可以自行计算散列值,然后与官方网站上公布的散列值进行对比。
基于口令的加密
单向散列函数也被用于基于口令的加密(PBE)
PBE的原理是将口令和盐(salt 通过伪随机数生成器产生的随机数)混合后计算其散列值,然后将这个散列值用作加密的秘钥。
消息认证码
使用单向散列函数可以构造消息认证码
消息认证码是将“发送者和接受者之间的共享密钥”和“消息”进行混合后计算出的散列值。使用消息认证码可以检测并防止通信过程中的错误、篡改以及伪装。
数字签名
在进行数字签名时也会使用单向散列函数
数字签名是现实社会中的签名和盖章这样的行为在数字世界中的实现。数字签名的处理过程非常耗时,因此一般不会对整个消息内容直接施加数字签名,而是先通过单向散列函数计算出消息的散列值,然后再对整个散列值施加数字签名。
伪随机数生成器
使用单向散列函数可以构造伪随机数生成器
密码技术中所使用的随机数需要具备“事实上不可能根据过去的随机数预测未来的随机数列”这样的性质。为了保证不可预测性,可以利用单向散列函数的单向性。
一次性口令
使用单向散列函数可以构造一次性口令一次性口令经常被用于服务器对客户端的合法性认证。在这种方式中,通过使用单向散列函数可以保证口令只在通信链路上传送一次,因此即使窃听者窃取了口令,也无法使用。
单向散列函数的具体例子
MD4、MD5
MD4现在已经不安全了。
MD5的强抗碰撞性已经被攻破,也就是说,现在已经能够产生具备相同散列值的两条不同的消息,因此它也已经不安全了
MD4和MD5中的MD是消息摘要(Message Digest)的缩写
SHA-1、SHA-256、SHA-384、SHA-512
SHA-1能够产生160比特的散列值的单向散列函数,不过它已经被列入“可谨慎运用的密码清单”,即除了用于保持兼容性的目的以外,其他情况下都不推荐使用。
SHA-256、SHA-384、SHA-512的散列长度分别为256比特、384比特和512比特,这些单向散列函数合起来统称SHA-2,它们的消息长度也存在上限(SHA-256的上限接近于264比特,SHA-384和SHA-512的上限接近于2128比特)
SHA-1的强抗碰撞性已于2005年被攻破也就是说,现在已经能够产生具备相同散列值的两条不同的消息,不过SHA-2还尚未被攻破。
RIPEMD-160
RIPEMD-160已经被列入“可谨慎运用的密码清单”即除了用于保持兼容性的目的以外,其他情况下都不推荐使用。
RIPEMD的强抗碰撞性已经与2004年被攻破,但RIPEMD-160还尚未被攻破,比特币使用的就是RIPEMD-160
SHA-3
SHA-3是一种作为新标准发布的单向散列函数算法,用来替代在理论上已被找出攻击方法的SHA-1算法,于2012年正式确定将Keccak算法作为SHA-3标准。
Keccak最终被选为SHA-3的理由如下
- 采用了与SHA-2完全不同的结构
- 结构清晰,易于分析
- 能够适用于各种设备,也适用于嵌入式应用
- 在硬件上的实现显示出了很高的性能
- 比其他最终候选算法安全性边际更大
Keccak采用了海绵结构,输入的数据在进行填充之后,要经过吸收阶段和基础阶段,最终生成输出的散列值。
Keccak可以生成任意长度的散列值,但为了配合SHA-2的散列值长度,SHA-3标准中共规定了SHA3-224、SHA3-256、SHA3-384、SHA3-512这4种版本。在输入数据的长度上限方面,SHA-1为264-1比特,SHA-2为2128-1比特,而SHA-3则没有长度限制。
对Keccak的攻击
Keccak之前的单向散列函数都是通过循环执行压缩函数的方式来生成散列值的,这种方式称为MD结构,MD4、MD5、RIPEMD、RIPEMD-160、SHA-1、SHA-2等几乎所有的传统单向散列函数算法都是基于MD结构的。
Keccak采用了和MD结构完全不同的海绵结构,因此针对SHA-1的攻击方法对Keccak是无效的。目前还没有出现能够对实际应用中的Keccak算法形成威胁的攻击方法。
应该怎么选择单向散列函数
MD5是不安全的,因此不应该使用。
SHA-1除了用于对过去生成的散列值进行校验之外,不应该被用于新的用途,而是应该迁移到SHA-2
SHA-2有效应对了针对SHA-1的攻击方法,因此是安全的,可以使用
SHA-3是安全的,可以使用
SHA-2(SHA-256、SHA-384、SHA-512)被列入了“电子政府推荐使用的密码清单”中。
对单项散列函数的攻击
暴力破解
利用文件的冗余性生成具有相同散列值的另一个文件,这就是一种针对单向散列函数的攻击。
寻找和"100万元合同"具备相同散列值的另一条不同的消息,这相当于一种视图破解单向散列函数的”弱抗碰撞性“的攻击这种情况下,暴力破解的次数根据散列值的长度计算出来,以SHA3-512为例,长度为512比特,最多需要尝试2512次就能够找到目标消息了,如此多的尝试次数在现实中是不可能完成的。
找出具有指定散列值的消息的攻击分为两种,即原像攻击和第二原像攻击,原像攻击是指给定一个散列值,找出具有该散列值的任意消息,第二原像攻击是指给定一条消息1, 找出另外一条消息2,消息2的散列值和消息1相同。
生日攻击
生日攻击的原理来自生日悖论,也就是利用了任意散列值一致的概率比想象中要高
注意:
在 N 个人中,保证至少有两个人生日一样的概率大于二分之一,那么 N 至少是多少?
先计算 N 个人生日全都不一样的概率,然后再用1减去这个值就可以了,最后发现当 N 取23时,概率为0.507297,大于二分之一。
Mallory所进行的生日攻击的步骤如下:
1、Mallory生成 N 个100万元合同
2、Mallory生成 N 个1亿元合同
3、Mallory将1的 N 个散列值和2的 N 个散列值进行对比,寻找其中是否有一致的情况
4、如果找出了一致的情况,则利用这一组100万元合同和1亿元合同来欺骗Alice
以512比特的散列值为例,对单向散列函数进行暴力破解所需要的尝试次数为2512次,而对同一单向散列函数进行生日攻击所需的尝试次数为2256次,因此和暴力破解相比,生日攻击所需的尝试次数要少的多。
单项散列函数无法解决的问题
单项散列函数能够辨别出“篡改”,但无法辨别出“伪装”
注意:此处的伪装例如:主动攻击者Mallory伪装成Alice,向Bob同时发送了消息和散列值,这时Bob能够通过单向散列函数检查消息的完整性,但是这只是针对发送的消息进行检查,而无法检查出发送者的身份是否被Mallory进行了伪装。
用于认证的技术包括消息认证码和数字签名消息认证码能够向通信对象保证消息没有被篡改,而数字签名不仅能够向通信对象保证消息没有被篡改,还能够向所有第三方做出这样的保证。