MD5加密和彩虹表
首先叙述一下彩虹表的原理。本部分内容、图片和例子基本来自英文维基的Rainbow table词条(Rainbow table)——中文维基中目前(2013年10月9日)尚无对应的词条——因此对本答案中这部分的转载请遵循维基的版权协议。
彩虹表的核心在于预先计算好的哈希链(Precomputed hash chains)。
当面对要破解的哈希函数H,首先要定义一个简化函数(reduction function)R,该函数的定义域和值域应该是和哈希函数相反的,通过该函数可以将哈希值约简为一个与原文相同格式的值("plain text" value)。需要强调的是,由于哈希函数H是不可逆的,所以对于密文进行R运算几乎不可能得到明文原文。例如,六位字母明文“aaaaaa”进行H运算后得到了“281DAF40”,而对“281DAF40”进行R运算后得到另一个六位字母格式的值“sgfnyd”。因为这个值落在H的定义域中,因此可以对它继续进行H运算。
就这样,将H运算、R运算、H运算……这个过程反复地重复下去,重复一个特定的次数k以后,就得到一条哈希链,例如:
这条链条并不需要完整地保存下来,只需要保存其起节点和末节点即可,例如上例中只需要保存起节点“aaaaaa”和末节点“kiebgt”。以大量的随机明文作为起节点,通过上述步骤计算出哈希链并将终节点进行储存,即可得到一张彩虹表。
这张彩虹表需要如何使用呢?例如,我们知道哈希运算后的密文为“920ECF10”,则先对其进行一次R运算,得到“kiebgt”。
正巧在本例中,它等于彩虹表中的一个末节点,因此我们可以猜测,明文有极大的可能存在于以起节点“aaaaaa”开头、末节点“kiebgt”结尾的这条哈希链中。(注意可能性并不是100%,因为函数H和R均有可能发生碰撞,从不同的输入值得到相同的输出值。)
为了验证我们的猜测,可以从起节点“aaaaaa”开始重复哈希链的计算过程:
算到这里我们发现,“sgfnyd”进行哈希运算的结果正是密文“920ECF10”,这样就找到了所需的明文。
如果不幸,第一次R运算后并未在彩虹表中找到对应的末节点,则需要继续重复H运算、R运算这样的步骤。可以发现,最多重复k次,我们即可断定,所需的明文在这张彩虹表中——已经找到了对应的末节点,并从起节点算出了明文;或是所需的明文不在这张彩虹表中——表中并未储存长度大于k的哈希链,因此再计算也没有意义了。
如果让我来解释哈希链的意义,我认为,每一条哈希链实际上是代表了属性相同的一组明文:每一个明文都可以通过起节点迅速的计算得出,计算次数不大于k,因而可以大大节约时间。对每一组明文,只需要保存其特征值(起节点和末节点),储存空间只需约1/k,因而大大节约了空间。
可以看出,当k越大时,破解一个哈希值的期望时间就越长,但彩虹表所占用的空间就越小;相反,k越小时,彩虹表本身就越大,相应的破解时间就越短。这正是保持空间、时间二者平衡的精髓所在。RainbowCrack中rtgen工具使用的默认k值好像是2100。极端的,令k=1,简化函数R(x)=x,这样的彩虹表就变成了通常的错误理解,即将明文、密文对应关系全部保存的表。此时由于k极小,因而得到的表的体积极大,甚至可能超出储存能力。(当然,对于范围较小的明文,如6位以下数字英文的组合,或是全世界常用密码的集合,生成k=1的表还是不费什么事的。)
在构造哈希链的时候,一个优秀的函数R功不可没。首先R需要能将值域限定在固定的范围——例如给定的长度范围、给定的字符取值范围等等——之内,否则的话,哈希链中大量的计算结果并不在可接受的取值范围内,一条链条无法对应多个明文,链条就失去了意义;其次R必须同哈希函数一样,尽量保证输出值在值域中的均匀分布,减少碰撞的概率。否则,多条哈希链碰撞得到同样的末节点,或是大量的明文无法在哈希链中出现,都会降低最终生成的彩虹表的价值。我没有继续深入研究已有的彩虹表工具中R的算法,但可以肯定这是彩虹表原理中的精髓所在。
多说一些,关于彩虹表的防御方式,其实都是与彩虹表的原理,即其生成步骤中用到的函数H有关。
最常用的方法,在其它的答案中也提到了,那就是加盐(salt),这其实是改变了哈希函数H的形式。由于彩虹表在生成和破解的过程中,都反复用到了函数H,H如果发生了改变,则已有的彩虹表数据就完全无法使用,必须针对特定的H重新生成,这样就提高了破解的难度。
防御彩虹表的另一种方法是提高H函数的计算难度,例如将H定义为计算1k次MD5后的结果。由于H在算法中的重复性,当单次H函数的计算耗时增加,意味着彩虹表的生成时间会大大的增加,从而也能提高破解的成本。
===========简化比喻的分隔线==============
如果将哈希后的密文比作一把锁,暴力破解的方法就是现场制作各种各样不同齿形的钥匙,再来尝试能否开锁,这样耗时无疑很长;我以前错误理解的“彩虹表”,是事先制作好所有齿形的钥匙,全部拿过来尝试开锁,这样虽然省去了制作钥匙的时间,但是后来发现这些钥匙实在是太多了,没法全部带在身上。而真正的彩虹表,是将钥匙按照某种规律进行分组,每组钥匙中只需要带最有特点的一个,当发现某个“特征钥匙”差一点就能开锁了,则当场对该钥匙进行简单的打磨,直到能开锁为止。这种方法是既省力又省时的。
网站密码加密原理(初级)http://blog.csdn.net/ubuntu64fan/article/details/7096642
http://www.cnblogs.com/luminji/archive/2011/05/24/2055021.html
MD5加密和彩虹表的更多相关文章
- 一种简单的md5加盐加密的方法(防止彩虹表撞库)
md5加密(或者说摘要算法)大家都很熟悉了 就不解释了 现在很多数据库设计都喜欢用单向加密的方式保存密码,验证时对提交的密码再次加密之后做密文对比 /// <summary> 使用MD5加 ...
- MD5加密算法中的加盐值 ,和彩虹表攻击 防止彩虹表撞库
一.什么是彩虹表? 彩虹表(Rainbow Tables)就是一个庞大的.针对各种可能的字母组合预先计算好的哈希值的集合,不一定是针对MD5算法的,各种算法的都有,有了它可以快速的破解各类密码.越是复 ...
- MD5小彩虹表
为方便日常查询,需要一个MD5小彩虹表,当然网上有比较多的这样的查询站点,但感觉最近使用起来十分不便. 因此,编写一个小程序,用来查询一些经常出现的MD5,也即弱口令MD5查询.采用python3编写 ...
- 使用crypto模块实现md5加密功能(解决中文加密前后端不一致的问题)
正常情况下使用md5加密 var crypto = require('crypto'); var md5Sign = function (data) { var md5 = crypto.create ...
- 驰骋工作流引擎-流程数据md5加密
关键字:工作流程数据加密 md5 数据保密流程数据防篡改软加密设置方式: 对工作流引擎的数据加密研究, 流程数据的加密方案与实现过程.输入图片说明需求背景1, 流程数据加密是为了防止流程数据被篡改 ...
- 【web安全】-- springboot实现两次MD5加密
一.为什么要做两次MD5 客户端MD5:HTTP在网络上是使用明文传输,用户输入的明文密码直接在网络上传输太危险.所以,在客户端先进行一次MD5(明文+固定盐). 服务端:服务端接受到后,也不是直接写 ...
- python之MD5加密
一. MD5加密import hashlib #Python3里的引用#import md5 #Python2里的引用 1. md5是不可逆的,不能解密2. 所有语言生成的md5串都是一样的 3. 不 ...
- MD5加密+加盐
了解: MD5加密,是属于不可逆的.我们知道正常使用MD5加密技术,同一字符,加密后的16进制数是不变的,自从出现彩虹表,对于公司内部员工来说,可以反查数据,获取不可能的权限,所以出现了salt算法. ...
- rainbow table 彩虹表
RainbowTable 的使用和性能的小测试 - SV的边界 - CSDN博客 https://blog.csdn.net/cecilulysess/article/details/4804707 ...
随机推荐
- vue写后台管理系统问题概述和解决方案
一个不错的Demo; http://xmall.exrick.cn/#/home 源码:https://gitee.com/Exrick/xmall-front/blob/master/src/pag ...
- Java 10 - Java Character类
Java Character类 使用字符时,我们通常使用的是内置数据类型char. 实例 char ch = 'a'; // Unicode for uppercase Greek omega cha ...
- CS229 6.5 Neurons Networks Implements of Sparse Autoencoder
sparse autoencoder的一个实例练习,这个例子所要实现的内容大概如下:从给定的很多张自然图片中截取出大小为8*8的小patches图片共10000张,现在需要用sparse autoen ...
- virt-install详解
man virt-install VIRT-INSTALL() Virtual Machine Manager VIRT-INSTALL() NAME virt-install - provision ...
- Cmder - 在右键菜单添加"Cmder Here"
使用命令行或终端工具的时候都有一个让我们觉得麻烦的问题,就是需要cd很多目录达到目标位置.在可视化操作系统下面我们一般都是已经处在目标目录了,这时需要执行某些命令如: python test.py 现 ...
- ace admin
.svg image/svg+xml.woff application/x-font-woff.woff2 application/x- ...
- jar 问题 : java.io.IOException: invalid header field
通过本文, 我们明白了什么是 jar的清单文件 MANIFEST.MF, 简单示例: E:\ws\Test\WEB-INF\classes>jar cvfm testCL.jar ListTes ...
- java 权重随机算法实现
import java.util.*; /** * 权重随机算法实现 * a b c d 对应权重范围 --- [0,1).[1,3).[3,6).[6,10) */ public class Ran ...
- CentOS 7 救援模式启用网卡及重新获取IP地址
重新自动获取IP地址命令: dhclient 启用网卡命令 ifconfig ens33 up https://blog.csdn.net/hongmin118/article/details/782 ...
- 如何解决Android帧动画出现的内存溢出
这几天在做动画的时候,遇到了一个OOM的问题,特此记录下来. 普通实现 实现一个帧动画,最先想到的就是用animation-list将全部图片按顺序放入,并设置时间间隔和播放模式.然后将该drawab ...