Hash 解读

什么是 Hash

其实,只要我们在互联网上活动,都会在无意中用到和 Hash 相关的内容。

举几个栗子,

当我们在互联网上下载软件 / 游戏时,官方站点在下载页面都会提供一串 MD5 的校验码,用来在软件下载完成后,校验原文件是否有被中间人拦截、篡改。这个 MD5 的校验码就是通过 Hash 函数来实现的。
那么原理是什么呢?

版本管理工具 Git 是通过什么方式来检查文件的更新呢?对比文件内容吗?

当我们在做一个站点时,一般都需要保存用户的敏感信息,比如登录密码、交易密码等。当我们的程序在保存到数据库以后,我们会发现数据库存储的都是一串很长的不可识别的字符串。这个字符串,也是 Hash 函数计算之后的结果。
为什么要这样呢?

当我们在访问 HTTPS 的站点时,浏览器是安装了为该网站颁发的数字证书的。在数字证书所包含的信息中,需要有证书指纹,防止证书被伪造。而生产证书指纹的算法,用的也是 Hash 函数。

那究竟什么是 Hash 函数?
Hash 函数是一种散列算法(Hash Algorithm), 又称哈希算法。算法有固定的要求,实现的方式确实多种多样的,但实现目的确是基本一致的。是一种从任意文件中创造小的数字「指纹」的方法。

散列算法就是一种以较短的信息来保证文件唯一性的标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。

当然,作为一种指纹,散列算法最重要的用途在于给证书、文档、密码等高安全系数的内容添加加密保护。这一方面的用途主要是得益于散列算法的不可逆性,这种不可逆性体现在,你不仅不可能根据一段通过散列算法得到的指纹来获得原有的文件,也不可能简单地创造一个文件并让它的指纹与一段目标指纹相一致。散列算法的这种不可逆性维持着很多安全框架的运营

Hash 算法的特点

一个优秀的 Hash 算法,将能实现:

  • 正向快速:给定明文和 Hash 算法,在有限的时间和有限的资源内能计算出 Hash 值
  • 逆向困难:给定 (若干) Hash 值,在有限时间内基本不可能逆推出明文
  • 输入敏感:原始输入信息修改一点信息,产生的 Hash 值看起来应该有很大的不同
  • 冲突避免:很难找到两段内容不同的明文,使得他们的 Hash 值一致 (发生冲突)。即对于任意两个不同的数据块,其 Hash 值相同的可能性极小;对于一个给定的数据块,找到和它 Hash 值相同的数据块极为困难。
1
2
MD5("version1") = "966634ebf2fc135707d6753692bf4b1e";
MD5("version2") = "2e0e95285f08a07dea17e7ee111b21c8";

可以看到仅仅一个字符的变更,二者的 Hash 值就已经完全不同了

基于 Hash 算法的特性,在不同的应用场景(数据结构和安全领域)下,具体的 Hash 实现,会对其中的某几个特点有所侧重。

Hash 在管理数据结构中的应用

在用到 Hash 管理的数据结构中,就对速度比较重视,对抗碰撞不太看中,只要保证 Hash 均匀分布就可以。比如 HashMap、Hash Key 存在的目的是加速键值对的查找,key 的作用是为了将元素适当地放在各个 Bucket 里,对于抗碰撞的要求没那么高。比如,缓存服务器中常用到的一致性 Hash。

Hash 在密码学中的应用

在密码学中,Hash 算法的作用主要是用于消息摘要和签名,换句话说,它主要用于对整个消息的完整性进行校验。

关于服务器存储密码的案例

其实把 Hash 算法当成是一种加密算法,这是不准确的。我们知道加密总是相对于解密而言的,没有解密何谈加密呢,Hash 的设计以无法破解为目的的。
并且如果我们不附加一个随机的 salt 值,Hash 口令是很容易被字典攻击入侵的。


REF: Hash算法总结


Hash 解读
http://kenneth-hao.github.io/2018/01/13/deep-in-hash/
作者
Yuewen
发布于
2018年1月13日
许可协议