MD5和SHA-1

转载自大神https://blog.csdn.net/shsalex/article/details/52300515
MD5和SHA-1都是我们耳熟能详的术语了,很多人可能知道他们跟加密有关系,但是他们是怎么做到加密的,他们各自的特点又是什么。我来简单的讲一讲。

MD5和SHA-1都被称作哈希(Hash)函数,用过Java语言的人对这个术语应该相当熟悉。Java类库里的Object类定义了hashCode这个函数,但是java的概念略有不同。正式的哈希函数的定义是“把任意长度的数据计算成固定长度的数据”。也就是说函数的输入是任意长的,输出总是固定长度的。MD5和SHA-1是两种加密用哈希函数,MD5的返回值总是128bit的,SHA-1的返回值是160bit,都是固定长度。MD5如果按十六进制表示的话是32位十六进制的数,SHA-1是40位十六进制的数。

你可以用下面两个网站试用这两个函数,这样有个感性认识:

MD5:http://md5-hash-online.waraxe.us/

SHA-1:http://sha1-hash-online.waraxe.us/

你输入任意长度的字符串,都会返回给你相应固定长度的十六进制返回值。这两个函数的返回值都被称为信息摘要(Message Digest,实际上MD就是Message Digest的缩写,SHA就是 secure hash algorithm 安全哈希算法的缩写。

那么两个函数为什么可以用在加密上呢?因为他们都有这几个特性

(1)都是“不可逆”的函数。不存在一个算法能够由哈希值倒算出原始信息。
(2)对原始信息的任何一点改变都会导致结果的哈希值巨大的不同。举个例子,假如原始数据是几百万字的文章,你在其中哪怕改动一个标点,计算出的哈希值都会有很大的变化。
(3)运算代价是相对较低的。普通的AMDOpteron 2.2GHz的芯片,每秒可以计算出335MB数据的MD5值,可以计算192MB数据的SHA-1值。  
(4)类似于1,除非通过蛮力的穷举法,否则无法找到两段不同的信息而有相同的哈希值。

那么这两个函数的特点在哪里呢?特点在于都能“通过哈希值唯一标识原信息”。这个怎么讲,就是比如原始信息是A,我知道原始信息的哈希值Ha,如果我有另一段信息,这段信息的哈希值也是Ha的话,我就能“以极大的可靠性”断定这另一段信息就是A。也就是说哈希值能“唯一”标识原始信息。原因是什么呢?

两段不同信息“碰巧”有着相同的哈希值的概率是很低的,对于MD5来说是2的128次方分之一,这个数字是多小呢:太阳的表面积是6万亿平方公里,一个原子的截面积大约是1平方纳米,假设你是一个原子,把你放在56个太阳中任意一个的表面,这个概率是我在这56个太阳上随意指定一点,正好点中你的概率,而你是一个小小小的原子。对SHA-1来说,这个概率就更低了。
那么有没有办法人工伪造一段信息正好有Ha这个哈希值呢?根据上面的1和4,这个可能性是很低的,要通过穷举法的巨大的运算量才能做到。

那么他们通常有什么应用呢?

  1. 密码加密(很常用的一种用法)

比如我有一个网站,用户注册的时候会输入用户名密码,大家都知道如果密码是明文的方式存储在数据库里的话,如果这个数据泄漏或者内部人员作恶的话,会造成信息安全问题。所以通用的做法是把用户输入的密码做MD5或SHA-1的运算,把返回的固定长度的哈希值存储在数据库中。比如用户的密码是”bigcat”,实际存储在数据库中的值是它的SHA-1的值a748bf7fee2289b22d448ed8efde10a68f7d1cf9。因为这两个函数的“不可逆”性,所以任何人拿到这个hash值是无法知道用户的明文密码的。这样的设计还有另外一个好处,就是可以一定程度上防止SQL注入。

  1. 文件校验

在网上下载大尺寸文件的时候常见到网站同时会提供这个文件的MD5的值,它的作用是用户下载后可以在下载文件基础上计算MD5的值,如果和网站提供的MD5是相同的说明文件在下载过程中没有损坏或者说文件没有被恶意网站修改。

  1. 工作量证明(Proof ofWork)

上面两种应用比较常见,工作量证明就不那么常见了。这里有一篇关于工作量证明的很好的文章:http://www.zhihu.com/question/22369364/answer/23600737。

我们知道,人们设计密码时都会考虑好记和简短,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码。

  加Salt可以一定程度上解决这一问题。既然你不想记住复杂的密码,我作为服务商由不想你的密码泄露,所以我让系统生成一些随机字符串,把这些随机字符串和你的密码拼接在一起,然后调用hash函数生成hash值,这些随机字符串会被保存到数据库中。如这里写图片描述
  所谓加Salt方法,就是加点“佐料”。其基本想法是这样的:当用户首次提供密码时(通常是注册时),由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,已确定密码是否正确。

  这里的“佐料”被称作“Salt值”,这个值是由系统随机生成的,并且只有系统知道。这样,即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,他们的散列值也是不同的。即便黑客可以通过攻击数据库的hash值和salt,要想通过这两个数据获得用户的密码也是难于上青天。
  这里推荐一个解密MD5的网站
  解密MD5
网上的暴力破解其实也是利用这个原理,
他把许多已知明文的,用MD5加密后,把MD5串值保存起来。你要反查,他实际上是在数据库中查找加密过的MD5串,是否有与你查询的MD5串相同,如果相同的话,就把明文给你看

你可能感兴趣的:(安全)