散列、加密、编码 漫谈

转载

https://www.cnblogs.com/shawnye/p/6741492.html

 

散列、加密、编码 漫谈

散列(又叫Hash)和加密在身份校验、敏感信息传输等应用中用途广泛。

把他们放在一起写的原因是,网上太多资料,将散列和加密的概念混为一谈,误导性极大。

由于编码/解码运算和上述二者有一定的相似之处,因此放在这里一并讲述。

注:本文中,为了表述严谨,所有的“位”代表的是字符个数之意,而bit则指代计算机数据中的基本单位比特。

1.三者的共同点

它们都表述了一种映射关系,将原始数据A映射到新的数据B。

在散列运算中,B一般称之为摘要,英文为digest. 其代表算法有MD5,SHA1, SHA256等。从A -> B的运算,称之为散列、哈希;从B -> A的运算(严格意义上来说,它不算一种运算)是不存在的,当然可以通过一些其他的手段比如查表法来实现,这个在下文中会谈到。

在加密运算中,A一般称之为明文或原文,B一般称之为密文。A->B的运算,称为加密;反之,即为解密。

而在编码中,A->B的运算称为编码,反之为解码。

2.三者的区别

散列

在散列运算中,是将一个较长的数据A,运算成为一个较短的数据B,如MD5的128bits,SHA1的160bits。

以字符a举例,它的MD5值是0cc175b9c0f1b6a831c399e269772661。一共32个字节,每个字节占用8bit,为什么说MD5是128bit呢?原因在于这是十六进制表示,每个字符的范围从0-9,a-f,每一位的可能性只有十六种,对应原始二进制的4bit,因此是32 x 4 = 128bit。

以MD5为例,谈谈它的几个重要特点。

  • 不可逆。即无法找到一个算法,从B逆推出A。
  • A的微小改变,会引起B的显著不同。举个例子,动手计算下字符A的MD5值为0cc175b9c0f1b6a831c399e269772661,B的MD5值为92eb5ffee6ae2fec3ad71c777531578f,相差巨大。
  • 必然存在多个数据有相同的MD5值。从一个接近无限的元素集合映射到一个有限的元素集合,必然有多个元素A被映射到相同的元素B。

基于以上三点,MD5的一个重要应用就是,证明数据在传输过程中有没有受损,或是被篡改。

如在网络上下载一些较大的文件如系统镜像时,下载站通常会提供MD5校验值,下载完成后对文件计算MD5,与网站提供的值比对,即可知道文件下载的是不是正确的,或是有没有损坏。

又如网站登录时,服务端明文保存用户名密码是一件极为不安全的事情,因此在过去很长的一段时间里,网站都是保存用户密码的MD5值。用户登录时,js会计算并提交密码的MD5值到服务端作比对,如果一致,则认为登录成功。

上述做法看上去没什么问题。由于MD5不能逆推出原文,因此,暴力穷举成为了唯一的办法。所谓的暴力穷举,指的是计算一定范围内字符串的MD5值,并建立反向映射关系。比如我计算出“123456”的MD5值是E10ADC3949BA59ABBE56E057F20F883E,我把它存在一张表里,key是E10ADC3949BA59ABBE56E057F20F883E,value是“123456”。再遇到同样的MD5值,就知道其原文是“123456”。因此,随着我计算范围的扩大,这个表会越来越大,覆盖的原文的面积也会越来越广。这样的MD5-原文的反向映射表,通常称为彩虹表。因此,为什么再三强调密码要够复杂,弱密码的MD5早已存在于彩虹表里,被查表破解是分分钟的事情。实际上,查表破解一直以来就是一个经典的破解办法,其实质,就是穷举。

查表,是从MD5“逆推出”原文的唯一办法。

针对暴力查表破解,人们又想出了一个新的解决方法,即加盐。所谓加盐,即在原始的密码后加上“盐”,并且,每个用户的盐不同。这个盐是保存在服务端的。登录时,先从服务端获取该用户的盐值,并加到用户的密码字符串后,然后再计算MD5值提交验证。由于每个用户的盐不一样,所以,即使用户用了相同的密码,其MD5都是不一样的,因为加盐后的原文不一样了。加盐可以说是现今比较安全的一种做法,毕竟Hacker不可能针对每个用户的不同的盐值去单独建立一张彩虹表,成本太高,收益太小。

最后谈谈MD5碰撞。所谓的MD5碰撞算法,指的是,在已知原文A和MD5值B的情况下,通过该碰撞算法,在有限的时间里,构造出一个A‘,拥有相同的MD5值B。

该算法的潜在应用,更多的在于伪造、篡改信息。比如我今天发出一封邮件,邮件内容是A:“往Jack账户上转帐10000元。”,并把该邮件的MD5值通过另外一种方式发给了收件人。那么通过该碰撞算法,我们在截获该邮件后,通过MD5碰撞,构造出邮件A‘:“往John账户上转帐10000元。”,假设二者的MD5相同,收件人收到邮件并比对MD5后,确认邮件无误,但是却将钱转给了别人。

看起来很危险,但实际操作起来难度要大的多。因为通常情况下,A和A‘是大相径庭的两个数据,相似度极低,可能A有10个字节,A’却有上百MB;即便能让它们在特定格式下,可见内容一样,但大小差异如此之大,收件人多半会起疑心。

因此,针对所谓MD5不安全、被破解的“大新闻”,还是不要像某些媒体一样,“见得风是得雨”。

 加密

加密的过程,同样通过某种算法,将原文A变换成不可读的密文B。与散列操作不同的是,这个运算是可逆的,存在一种解密算法,将密文变换回可读的原文A。

比如,我现在可以自定义一个加密算法,对原始的数据(以字节为单位)每个字节循环右移四位。解密的方式很简单,密文每个字节循环左移四位。在没有人知道我这种加密/解密算法之前,信息传输都是安全的。实际操作中,它很容易被破解。比如要利用它传送大批量的文本信息,那么根据英文中出现次数最多的字母是E这个统计规律,很容易就知道E对应的密文,进而破解。

所以,密码学的一个重要原理就是:

加密的安全性,不能依赖于加密算法本身的保密性。也就是说,即使公开你的算法,别人仍然破解不了你的数据,或者破解的成本远远高于收益。

举个例子,https中的不对称加密方式,加密/解密的算法完全公开;参与通信的每一个成员,均拥有一个密钥对,分为公钥和私钥。公钥为公开信息,你可以放在互联网上随意下载;私钥为隐私信息,必须妥善保管。发送方利用接收方的公钥加密信息,接收方在接收到信息以后利用自己的私钥进行解密。这也就确保了,只有你的接收方,知道通信的内容,别人没有私钥是无法解密的。整个通信过程的安全性由以下几点保证:

  • 加密不可逆。即密文无法利用公开信息(公钥等)逆推出原文。
  • 公钥无法通过某种运算获得私钥。

这种不对称加密还可以应用在数字签名中。举例,一次HTTPS POST请求中,发送方对整个HTTPS request body计算出一个摘要,并用自己的私钥对其加密,附在request header里。接收方对request body利用同样的算法计算出摘要A,再将request header里的加密摘要用发送方的公钥解密,得到摘要B,对比A和B是否一致,即可知道传输的消息是否被篡改。

当然,以上所有安全的前提,都是建立在私钥本身的安全性上的。如果你的私钥被人拿走了,那谁都救不了你。

编码

编码/解码操作与加密/解密操作非常类似,主要的区别在于,编解码的算法完全公开透明,只是为了方便信息传输而更换一种表现形式,并不具有任何隐私性。

比如BASE64,就应该称为编码,而不应称为加密。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值