散列、加密、编码 漫谈

散列(又叫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。

以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不安全、被破解的“大新闻”,还是不要像某些媒体一样,“见得风是得雨”。

未完待续。

时间: 2024-12-21 11:55:38

散列、加密、编码 漫谈的相关文章

MD5和sha1加密算法--散列加密技术 MD5:128bit的大整数

在很多电子商务和社区应用中,我们都要存放很多的客户的资料,其中包括了很多的隐私信息和客户不愿被别人看到的信息,当然好有客户执行各种操作的密码,此时就需要对客户的信息进行加密再存储,目前有两种比较好的加密算法:MD5和sha1. 这两种加密算法都属于散列加密技术.所谓散列加密就是无论输入的字符串是什么,有多大,加密后都将变成唯一的定长的加密串. 首先介绍一下MD5,MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Secu

.NET加密方式解析--散列加密

在现代社会中,信息安全对于每一个人都是至关重要的,例如我们的银行账户安全.支付宝和微信账户安全.以及邮箱等等,说到信息安全,那就必须得提到加密技术,至于加密的一些相关概念,在这里就不说了. 这一次将会主要讲解.NET的加密方式,接下来将会分别介绍散列加密,对称加密,非对称加密等等加密方式在.NET中的应用,本文主要讲解散列加密在.NET中的应用实例. 一.DotNet散列算法概述 说到散列应该都不会陌生,并且首先都会想到MD5加密,但是对于散列更加深入的了解,恐怕知道的人就不会那么多了.散列算法

单向散列加密

开发中有一种场景,就是只需要验证正确性而不需要知道它的原文,只需要知道这个值是否存在是否相等就可以了.比如前端登录将用户的密码加密给服务端并存储到数据库.或者验证文件唯一性等.这时就要用到单向散列加密. 单向散列函数特点 1. 对任意长度的消息散列值是定长的. 2. 散列计算速度快,非常高效. 3. 明文不同,散列加密后的密文一定不同:明文相同,散列加密后密文一定相同. 4. 具备单向性,无法逆推计算. 单向散列函数也被称为哈希函数,摘要函数或者杂凑函数.其经典算法有 md5 | sha | s

Linux工具开发[02]---编程实现对输入字符序列变换(编码/加密/散列)方式的智能判定

怎样简单实现一个能够智能判定输入字符序列变换方式的小程序 本文由CSDN-蚍蜉撼青松 [主页:http://blog.csdn.net/howeverpf]原创,转载请注明出处! 问题描写叙述: 在分析网络数据包或者研究安全问题时.经常会遇到变换后的字符序列.而是否能准确识别密文的变换算法,对进一步的分析工作非常关键. 经常使用的变换算法包含但不限于:Base64.URL编码.HTML编码.MD5散列.DES加密.RSA加密等. 要求: 1)在理解算法原理及密文特点的基础上.使用随意编程语言实现

Linux工具开发---2编程实现对输入字符序列变换(编码/加密/散列)方式的智能判定

如何简单实现一个可以智能判定输入字符序列变换方式的小程序 本文由CSDN-蚍蜉撼青松 [主页:http://blog.csdn.net/howeverpf]原创,转载请注明出处! 问题描述: 在分析网络数据包或者研究安全问题时,经常会遇到变换后的字符序列.而能否准确识别密文的变换算法,对进一步的分析工作很关键.常用的变换算法包括但不限于:Base64.URL编码.HTML编码.MD5散列.DES加密.RSA加密等.要求: 1)在理解算法原理及密文特点的基础上,使用任意编程语言实现,当输入一段密文

.Net加密与解密——散列运算

一,散列运算的特点 1,散列运算是不可逆的,可以将散列运算理解为单向的加密: 2,任何两个不相同的文件,哪怕只有一个字节的细微差别,得到的摘要都是完全不同的.这个特点的意义在于,可以用来判断消息是否被篡改,即解决完整性的问题. 3,无论原始消息的大小如何,运算得出的摘要的信息是固定长度,摘要的长度根据散列算法的不同而不同. 二,利用散列运算判断消息是否被篡改的流程 1,发送放对消息进行散列运算,得到消息摘要,发送消息和摘要,并说明获得摘要所使用的散列算法. 2,接收方获得消息和原始摘要,使用相同

加密散列算法——MD5

引用wiki的定义,散列函数(或散列算法,英语:Hash Function)是一种从任何一种数据中创建小的数字"指纹"的方法.该函数将数据打乱混合,重新创建一个叫做散列值的指纹.散列值通常用来代表一个短的随机字母和数字组成的字符串.好的散列函数在输入域中很少出现散列冲突.在散列表和数据处理中,不抑制冲突来区别数据,会使得数据库记录更难找到.(具体专业术语请自行度娘) MD5是单向散列算法的一种,全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2.MD

数字签名、数字证书、对称加密算法、非对称加密算法、单向加密(散列算法)

数字签名是什么? 1. 鲍勃有两把钥匙,一把是公钥,另一把是私钥. 2. 鲍勃把公钥送给他的朋友们----帕蒂.道格.苏珊----每人一把. 3. 苏珊给鲍勃写信,写完后用鲍勃的公钥加密,达到保密的效果. 4. 鲍勃收信后,用私钥解密,看到信件内容. 5. 鲍勃给苏珊回信,写完后用Hash函数,生成信件的摘要(digest). 6. 然后,鲍勃使用私钥,对这个摘要加密,生成"数字签名"(signature). 7. 鲍勃将这个签名,附在信件下面,一起发给苏珊. 8. 苏珊收信后,取下数

【Java-加密算法】对称加密、非对称加密、单向散列

一提到加密,就会联想到数字签名,这两个经常被混淆的概念到底是什么呢? 加密:加密是一种以密码方式发送信息的方法.只有拥有正确密钥的人才能解开这个信息的密码.对于其他人来说,这个信息看起来就像是一系列随机的字母.数字和符号.如果你要发送不应该让其他人看的敏感信息时,加密是特别重要的. 数字签名:数字签名是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法.一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证. 加密与数字签名的区别 加密同数字签名