单向散列函数

单向散列函数的说明

  1. 单向散列函数也称为消息摘要函数, 哈希函数 或者 杂凑函数
  2. 单向散列函数输出的散列值又称为消息摘要 或者 指纹

单向散列函数的特点

  1. 加密后密文的长度是定长的(即对任意长度的消息三列,得到的散列值是定长的)
  2. 散列计算速度快,非常高效
  3. 如果明文不一样,那么散列后的结果一定不一样
  4. 如果明文一样,那么加密后的密文一定一样(对相同数据加密,加密后的密文一样)
  5. 所有的加密算法是公开的
  6. 具备单向性,不可以逆推反算

单项散列函数的经典算法

  1. MD4
  2. MD5
  3. SHA1
  4. SHA256
  5. SHA512

MD5和SHA256是非常常用的两种单向散列函数,虽然MD5在2005年已经被中国密码学家王小云攻破,但是也还是在被大规模使用,现在比较常用的是SHA256算法,安全性暂时未有被破解。在BITS系统中,所有的索引都是通过sha256进行加密,即便知道了索引,在不知道原文的情况下,对知道者来说,也只是是一串无意义的字符串。

单向散列函数的常见应用场景

  1. 数据库中保存用户密码
    比如前段时间频频爆出一些公司的数据库被爆,用户的账户密码以明文存在,大量资料流出这样的做法是极其不负责和危险的。
    最好的方法就是将用户的密码通过单向散列函数输出到数据库,每次登录时对比散列值即可。由于单向散列函数的不可逆性,就算数据库被盗取,也没有办法得到用户的信息。
    (某些自称破解单向散列函数的网站使用的方法其实是低级的穷举法,保存大量常用明文的散列值,这样做是很愚蠢的。有很多方法可以应对,比如一种叫做“加盐”的常用方法,将用户的信息后面统一加上诸如$%*^&这样的字符,然后计算散列值存入数据库中,或者可以计算散列值的散列值,这样可以保证绝对的安全性。)

  2. 防止文件篡改
    目前大部分提供下载服务的网站都有提供文件的SHA256值,这是因为单向散列函数具备防篡改的效果,若是下载的文件的SHA256和网站提供的值不符,则可能此文件已经遭到了修改,可能含有病毒或者是盗版等等。。。接下来的代码中我们也会来实现计算文件的SHA256值。

  3. 数字签名
    在进行数字签名时也会使用单向散列函数。
    数字签名是现实社会中的签名和盖章这样行为在数字世界中的实现。数字签名的处理过程非常耗时,因此一般不会对整个消息内容直接使用数字签名,而是先通过单向散列函数计算出消息的散列值,然后再对这个散列值使用私钥加密,得到的就是数字签名。

  4. 伪随机数生成器
    使用单向散列函数可以构造伪随机数生成器。
    密码技术中所使用的随机数需要具备“事实上不可能根据过去的随机数列预测未来的随机数列”这样的性质。为了保证不可预测性,可以利用单向散列函数的单向性。

  5. 秒传
    很多诸如某云盘,某网盘这样的公司利用单向散列函数的特性实现秒传的效果。
    单向散列函数就像文件的指纹一样,当用户上传文件时,首先计算一下此文件的单向散列值,将此值在数据库中进行查找,若存在相同值,证明此用户上传的文件已经存在相同的,所以无需上传,共享即可。如此可大幅降低服务器负载,大幅缩减存储空间,实现去重的效果。

参考资料

什么是散列函数:https://web.archive.org/web/20061206022506/http://www.rsasecurity.com/rsalabs/node.asp?id=2176
散列函数:https://zh.wikipedia.org/wiki/%E6%95%A3%E5%88%97%E5%87%BD%E6%95%B8
sha家族:https://zh.wikipedia.org/wiki/SHA%E5%AE%B6%E6%97%8F
彩虹表:https://zh.wikipedia.org/wiki/%E5%BD%A9%E8%99%B9%E8%A1%A8