一、什么是彩虹表?
彩虹表(Rainbow Tables)就是一个庞大的、针对各种可能的字母组合预先计算好的哈希值的集合,不一定是针对MD5算法的,各种算法的都有,有了它可以快速的破解各类密码。越是复杂的密码,需要的彩虹表就越大,现在主流的彩虹表都是100G以上。
二、上哪找彩虹表去?
现在有很多大牛已经把自己的彩虹表共享出来了,所以你可以去下载。还有一种方法就是自己通过工具生成。
不过自己生成有点不切合实际,生成小的彩虹表吧数据少,可以破解密码的位数少(复杂程度低),而且费时费力,4核4GB内存的机器,生成2GB彩虹表,需要花费7天时间,而7天按1MB的带宽(160K/S左右)几乎可以下载30GB左右。
生成的工具可以用RainbowCrack也可以用Cain。网上很容易搜索到下载地址的。
加盐值可以抵抗彩虹表攻击 ,最好每次使用的盐值要动态生成.
我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码。
加Salt可以一定程度上解决这一问题。所谓加Salt方法,就是加点“佐料”。其基本想法是这样的:当用户首次提供密码时(通常是注册时),由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,已确定密码是否正确。
这里的“佐料”被称作“Salt值”,这个值是由系统随机生成的,并且只有系统知道。这样,即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,他们的散列值也是不同的。即便黑客可以通过自己的密码和自己生成的散列值来找具有特定密码的用户,但这个几率太小了(密码和salt值都得和黑客使用的一样才行)。
下面以PHP示例,讲解md5($pass.$salt)加密函数。
<?php
function hash($a) {
$salt=”Random_KUGBJVY”; //定义一个salt值,程序员规定下来的随机字符串
$b=$a.$salt; //把密码和salt连接
$b=md5($b); //执行MD5散列
return $b; //返回散列
}
?>
调用方式:$new_password=hash($_POST[password]); //这里接受表单提交值,并进行加密
下面详细介绍一下加Salt散列的过程。介绍之前先强调一点,前面说过,验证密码时要使用和最初散列密码时使用“相同的”佐料。所以Salt值是要存放在数据库里的。
用户注册时,
- 用户输入【账号】和【密码】(以及其他用户信息);
- 系统为用户生成【Salt值】;
- 系统将【Salt值】和【用户密码】连接到一起;
- 对连接后的值进行散列,得到【Hash值】;
- 将【Hash值1】和【Salt值】分别放到数据库中。
用户登录时,
- 用户输入【账号】和【密码】;
- 系统通过用户名找到与之对应的【Hash值】和【Salt值】;
- 系统将【Salt值】和【用户输入的密码】连接到一起;
- 对连接后的值进行散列,得到【Hash值2】(注意是即时运算出来的值);
- 比较【Hash值1】和【Hash值2】是否相等,相等则表示密码正确,否则表示密码错误。
有时候,为了减轻开发压力,程序员会统一使用一个salt值(储存在某个地方),而不是每个用户都生成私有的salt值。
关于MD5
MD5本身是不可逆的散列加密算法。此前山东大学的一个教授给出的并不是真正意义上的逆向破解,只不过是找到缩短碰撞时间的方法。给定任意密文,立即还原原始报文,这种基于MD5的逆向解释算法至少到目前为止,还没有任何一个人或者组织公布出来。
所以,对于MD5,目前公认最有效的途径只有一个,就是基于穷举法的暴力破解。
这种方式取决于原始报文的长度、编码等等,使用和原始密文同样的MD5加密方式,对加密结果和原始密文进行比对,如果加密内容过长,编码构成很复杂,基本可以判定为不可能。
关于AES
AES是一种基于私钥的对称加密算法。也就是说,AES,可以通过私钥进行正向加密和逆向解密。这点上和MD5是有区别的。
AES的私钥长度分为三种128、192和256三种。所以,对于AES密文的破解其实和常规的对称算法一样,穷举私钥。
理论上来说,AES的破解难度要小于MD5,毕竟私钥的最大长度为256Byte。但是目前,似乎除了穷举私钥并没有更好的方法来获取私钥。
如果想破解一个加密算法,建议先去研究一下需要破解这个加密算法。可以是数学模型/公式,或者直接去查各种语言对应的源码。如果真的存在有牛人可以做出MD5的逆向算法;或者不需要私钥就能获取AES的原始报文;更或者直接通过密文获取AES的私钥。。那么,这样的人可以去申请图灵奖了。
总结一下:
上面已经分别分析了2种加密算法,给出个结论:
如果单纯的是想破解密文,建议还是放弃吧。
如果是想模拟报文加密,可以考虑从程序里把AES的私钥搞出来。很多程序的私钥都是放在程序里的。
如果还有其它,不如考虑绕过加密部分,比如考虑一下在验证的判断上打打主意,甚至把加密部分去掉直接获取原始报文。