彩虹表

来源:互联网 发布:dr.com for mac 编辑:程序博客网 时间:2024/04/28 01:19

转自:http://m.blog.csdn.net/article/details?id=51356844
几乎现代所有不可逆的加密算法都是基于“取余数”。简单来说,就是“被除数”是密码明文,“余数”是存储在数据库中的密码密文,“除数”就是加密过程,而“商”则被丢弃了。
被除数 % 除数 = 余数(商被丢弃)
明文 % 加密过程 = 密文

将用户的密码明文加密后得到的密文,与服务器的数据库记录比较,如果相符,则认为密码正确。
因此,理论上来说,即使攻击者获得了密码密文,也不可能获得密码明文。
但如果,这个数据库被盗了,那什么密码都无所遁形。
彩虹表就是基于这一想法实现的,虽然不知道完整的数据库,但我可以根据人们的习惯自己大数据一个明文、密文对照数据库。而这个数据库就是“彩虹表”。
因为”检索“一定比”加密运算“快很多,所以使得“彩虹表”的暴力破解成为可能。
比如,“123456”的md5是“e10adc3949ba59abbe56e057f20f883e”。这样攻击者在只需要在彩虹表中查后面那一串密文,就能知道密码明文是123456
所以说,简单的直接加密存储已经难以满足要求。
现在流行的比较安全的普通加密存储密码的方法,是“MD5+盐(salt)”法。
假设说用户的密码是123456,用户名是abc,网站名是ABC,那么数据库中存储的密码是ABCabc123456的MD5值“123785419aed644018cfef182148e895”。因为MD5算法的特点,明文只要改变一点,密文就会改变很多。所以说即使攻击者知道了ABC和abc,只要彩虹表中不存在ABCabc123456对应的值,那么攻击者还是破译不了。而这里面的网站名和用户名,被称为“盐(salt)”。
再进一步往大了说,这种情况下,即使同一个人在两个网站使用了相同的用户名和密码,加密得到的密文仍然是不同的两个,这就是所谓的“一站一密(码)”。即使在同一网站,两个不同的用户名使用了同样的密码,得到的仍然是不同的密文,这就是所谓的“一人一密”。这样就无形中增加了总密码密文的数量,使得所需的彩虹表体积大幅增加。
假设5个仅仅使用普通MD5加密的网站,每个网站都有相同的1000个用户,攻击者可以拿一个100G的彩虹表破解。
那么如果是使用MD5加盐的加密法,攻击者就需要5000倍大小的彩虹表,也就是500T,就算能破译也要花上大量的时间和精力。
所以,尽管MD5加盐的办法也不是绝对安全(不存在绝对安全)的,但是仍然可以在现阶段作为一个标准化的密码加密存储的解决方案。
————————————————
再补充一下关于密码传输的问题。
0. 默认HTTP会用明文传输密码。
1. 最安全(但是高成本)的做法:使用SSL。
2. 简单安全的做法:在网页使用javascript进行加密,然后传递密码密文。服务器端直接拿收到的密文和数据库做比较。
3. 使用其他的富客户端——例如Java Applet, Silverlight之类的,加密后传递密码。
4. 奇葩的做法:用户首先输入用户名,然后服务器返回密码密文,本机加密密码明文后作比较,向服务器发送比较结果。
————————————————
补充:关于工作量。
编程的工作量:标准的加密方法,都有现成的代码可以使用,编写程序时增加的工作量很小。
系统的工作量:加密运算是需要很多计算的,所以当然会增加系统的工作量——只是需要进行加密运算的次数很少(注册时运算一次、每次登陆时运行一次、重设密码时运行一次),所以时间复杂度是O(n),n是“登录人次”),呈线性增长,所以对系统的压力,在n较小是可以忽略不计。
维护的工作量:无论明文还是密文存储密码,均极少需要人工维护,工作量的增加可以忽略不计。
用户的工作量:注册及输入密码是工作量不变。明文存储密码可以进行“找回”;密文存储密码不可找回,只能重置。所以用户一旦忘记密码,使用密文存储密码的系统,用户需要进行两步操作;而使用明文的,可能只需要一步就可以了(如果用户不需要修改密码的话)。
总的来说,工作量增加的很小,安全性增加很多,因此采用加密方案是理所当然的。

0 0