单向散列函数
单向散列函数,one-way hash function,是用于解决确认消息和文件完整性和一致性,应用于消息认证场景。单向散列函数可以根据消息的内容计算出散列值,散列值就可以被用来检查消息的完整性。
单向散列函数也称消息摘要函数(message digest function)、哈希函数或者杂凑函数。单向散列函数的输入消息称为原像(pre-image),单向散列函数的输出称为消息摘要(message digest)或者指纹(fingerprint)。
经单向散列函数计算出的散列值长度是和原消息长度是无关的,无论多大的消息块经过单向散列函数计算出的散列值都是固定长度的,如常见的SHA-256单向散列函数,计算得到的散列值永远是256比特。
单向散列函数性质
输出长度固定
单向散列函数的输入值必须可以是任意长度的数据,且输出长度必须短且固定。
计算快速
单向散列函数的计算速度快,可以快速得到散列值。
抗碰撞性
为了确认消息的完整性,消息中即使是由1比特的改变,也必须产生不同的散列值。若两个消息产生的散列值一样,则称为碰撞(collision)。如果使用单向散列函数进行完整性检查,需要确保不可认为发现碰撞。密码技术使用的单向散列函数。都需要具备抗碰撞性。
单向性
单向性是指无法通过散列值反算出消息的性质。单向散列函数必须具备单向性,这个特性用于避免使用散列值被反解算出源消息。单向散列函数不是加密算法,所以无法进行解密。
单向散列函数的实际应用
检测软件是否被篡改
使用单向散列函数确认下载的软件是否被篡改,很多安全软件会将单向散列函数公布在官网上,用户可以在下载软件后,自行计算散列值,与官网散列值对比后,就可以确认下载的软件是否安全。
基于口令加密
单向散列函数被应用于口令加密(Password Based Encryption,PBE),PBE的原理是将口令和盐(slat,通过伪随机数生成器产生的随机值)混合后计算其散列值,再用散列值作为加密的密钥。
消息认证码
使用单向散列函数构造消息认证码也是单向散列函数常用的应用场景。消息认证码是将“发送者和接收者直接共享的密钥”和“消息”进行混合运算计算出的散列值,使用消息认证码可以检测并方针通信过程中的错误、篡改及伪装。
数字签名
进行数字签名时,也会使用单向散列函数。数字签名是先通过单向散列功函数计算出消息的散列值,然后再对这个散列值施加数字签名。
伪随机数生成器
使用单向散列函数构造伪随机,在之前的文章中也有提到,在伪随机数发生器内部使用单向散列函数,产生伪随机数序列。
一次性口令
使用单向散列函数可以构造一次性口令(one-time password)。一次性口令用于服务器对客户端的合法认证性。这种口令在通信链路上只使用一次,具有极高的安全性。
单向散列函数算法
MD4、MD5
MD——Message Digest缩写
MD4是由Rivest与1990年设计的单向散列函数,可以产生128比特的散列值,目前MD4的碰撞性已经被攻破,已不再安全。
MD5是由Rivest与1991年设计的单向散列函数,可以产生128比特的散列值,目前MD5的碰撞性也已经被攻破,也已不再安全。
SHA1、SHA2-256/384/512
SHA-1是美国国家标准技术研究所(NIST)设计的可以生成160比特的单向散列函数,SHA-1的消息长度存在上限,上限接近2的64次方比特。SHA-1目前已被列入“可谨慎使用密码清单”,因为在2005年已被攻破强碰撞性,所以SHA-1除了用于保持兼容性外,其他情况不推荐使用。
SHA2也是由NIST设计单向散列函数,分为SHA2-256/SHA2-384/SHA2-512不同的形式,散列值分别为256比特、384比特和512比特。SHA-2的消息长度存在上限,SHA2-256的上限接近2的64次方比特,SHA2-384/512的上限接近2的128次方比特,目前SHA2尚未被攻破可正常使用。
SHA-2的多种版本具体可见下表:
RIPEMD-160
RIPEMD-160是1996年Hans Dobbertin、Antton Bosselaers和Bart Preneel设计的一种可以产生160比特散列值的单向散列函数。目前RIPEMD-160尚未被攻破。
SHA-3
SHA-3是一种新标准单向散列函数,用来替代SHA-1,在2012正式确定将Keccak算法作为SHA-3标准。SHA-3和SHA-2目前都是安全的,SHA-3与SHA-2使用的是完全不同的算法结构,结构清晰,也更易于分析。SHA-3包含了SHA3-224、SHA3-256、SHA3-384、SHA3-512四种版本,SHA-3是没有数据输入长度限制的。