Hash

散列函数

Posted by BY on July 23, 2018

1. Hash算法与数字摘要

1. Hash定义

定义如下:h = H(m)

其中:

  • m :任意长度消息(不同算法实现,长度限制不同,有的哈希函数(SHA-3)不限制消息长度,有的限制(SHA-2),但即使有限制其长度也非常大,可以认为是任意长度消息)
  • H:哈希函数
  • h:固定长度的哈希值

Hash(哈希或散列)算法是非常基础也非常重要的计算机算法,它能将任意长度的二进制明文串映射为较短的(通常是固定长度的)二进制串(Hash值),并且不同的明文很难映射为相同的Hash值。

举个例子来说:

sha256(github.com) = 3aeb002460381c6f258e8395d3026f571f0d9a76488dcd837639b13aed316560

Hash算法的性质如下:

  1. 正向快速:给定明文和Hash算法,在有限时间和有限资源内能计算得到Hash值;

  2. 逆向困难:给定(若干)Hash值,在有限时间内很难(基本不可能)逆推出明文;

  3. 输入敏感:原始输入信息发生任何改变,新产生的Hash值都应该出现很大不同;

  4. 冲突避免:很难找到两段内容不同的明文,使得它们的Hash值一致(发生碰撞)

其中,冲突避免有时候又称为“抗碰撞性”,分为“弱抗碰撞性”和“强抗碰撞性”。如果给定明文前提下,无法找到与之碰撞的其他明文,则算法具有“弱抗碰撞性”;如果无法找到任意两个发生Hash碰撞的明文,则称算法具有“强抗碰撞性”。

2. 常见算法

目前常见的Hash算法包括MD5和SHA系列算法。

  • MD4(RFC 1320)MD是Message Digest的缩写。其输出为128位。MD4已被证明不够安全。

  • MD5(RFC 1321)是Rivest于1991年对MD4的改进版本。它对输入仍以512位进行分组,其输出是128位。MD5比MD4更加安全,但过程更加复杂,计算速度要慢一点。MD5已被证明不具备“强抗碰撞性”。

  • SHA(Secure Hash Algorithm)并非一个算法,而是一个Hash函数族。NIST(National Institute of Standards and Technology)于1993年发布其首个实现。目前知名的SHA-1算法在1995年面世,它的输出为长度160位的Hash值,抗穷举性更好。SHA-1设计时模仿了MD4算法,采用了类似原理。SHA-1已被证明不具备“强抗碰撞性”。

为了提高安全性,NIST还设计出了SHA-224、SHA-256、SHA-384和SHA-512算法(统称为SHA-2),跟SHA-1算法原理类似。SHA-3相关算法也已被提出。

目前,MD5和SHA1已经被破解,一般推荐至少使用SHA2-256或更安全的算法。MD5是一个经典的Hash算法,和SHA-1算法一起都被认为安全性已不足应用于商业场景。

3. 数字摘要

顾名思义,数字摘要是对数字内容进行Hash运算,获取唯一的摘要值来指代原始完整的数字内容。数字摘要是Hash算法最重要的一个用途。利用Hash函数的抗碰撞性特点,数字摘要可以解决确保内容未被篡改过的问题。

从网站下载软件或文件时,有时会提供一个相应的数字摘要值。用户下载原始文件后可以在本地自行计算摘要值,并与提供的摘要值进行比对,可检查文件内容是否被篡改过。

4. sha256

SHA256属于SHA(Secure Hash Algorithm,安全哈希算法)家族一员,是SHA-2算法簇中的一类,对于小于2^64次方位的消息,产生一个256位的消息摘要,长度为64位。

SHA-256其计算过程分为两个阶段:消息的预处理和主循环。在消息的预处理阶段,主要完成消息的填充和扩展填充,将所有输入的原始消息转换为n个512比特的消息块,之后对每个消息块利用SHA256压缩函数进行处理。

5. Hash攻击与防护

Hash算法并不是一种加密算法,不能用于对信息的保护。但Hash算法常用于对口令的保存上。例如用户登录网站需要通过用户名和密码来进行验证。如果网站后台直接保存用户的口令明文,一旦数据库发生泄露后果不堪设想。大量用户倾向于在多个网站选用相同或关联的口令。

利用Hash的特性,后台可以仅保存口令的Hash值,这样每次比对Hash值一致,则说明输入的口令正确。即便数据库泄露了,也无法从Hash值还原回口令,只有进行穷举测试。

然而,由于有时用户设置口令的强度不够,只是一些常见的简单字符串,如password、123456等。有人专门搜集了这些常见口令,计算对应的Hash值,制作成字典。这样通过Hash值可以快速反查到原始口令。这一类型以空间换时间的攻击方法包括字典攻击和彩虹表攻击(只保存一条Hash链的首尾值,相对字典攻击可以节省存储空间)等。

为了防范这一类攻击,一般采用加盐(salt)的方法。保存的不是口令明文的Hash值,而是口令明文再加上一段随机字符串(即“盐”)之后的Hash值。Hash结果和“盐”分别存放在不同的地方,这样只要不是两者同时泄露,攻击者就很难破解了。