[翻译]Python开发中的密码散列(Hashing)
杀戮 (乌云安全实验室的杂役) | 2015-01-04 23:17
去年7月的一篇小文,看着还不错,就翻译了,当然还是我自己的语气,对于文中的一些概念加了点注释。
话说当年linkedin 和 adobe被人爆了菊,而且他们不恰当的密码储存方式导致黑客能够破解密码并且去干一些很坏很坏的事情。
关于这个一个很重要的概念是 hashing 和 加密的区别,加密是可逆的,hashing不是。第二个很重要的概念是,MD5和SHA 在密码Hashing上都不合适,有两个原因。
1. 没有salts
没有Salts导致当年linkedin被打成了翔。
注释: 并不是很新的技术,Salts 是个”佐料”,貌似这个翻译恰当一些,融入Salts 的加密过程可以用于抵抗彩虹表这种残暴的凌辱。技术细节相当于 用户输入密码 12345,系统会生成一个随机的字符串xxxxxx 和密码连接,放入hash函数进行散列,最后系统储存salts值和hash值用于用户每次登陆进行比较。
Python代码:
import hashlib import os password = "password" salt = os.urandom(16) m = hashlib.md5() m.update(salt + password) m.hexdigest()
不过,这还是不够啊不够。
2. 速度快
(第一眼我也郁闷了,不过不要在意细节,请继续)
正常的密码散列比如MD5,不适合用在密码散列的第二个原因在于速度很快,对于大部分的算法,速度快是重点,当对于密码散列来说不是,当小白们的小电脑跑着普通的CPU的时候,不少黑客都开着GPU了,他们能够很快的进行密码破解,现代GPU能够在一秒之内进行千亿次MD5或者SHA运算。
特殊的密码散列一般在于解决这两个方面的原因。
3. 主流的密码Hashing
目前主流的观点是使用三种不同的hash函数用于密码hash , PBKDF2, Bcrypt and Scrypt。
当然老外也举办了一个 密码hashing的竞赛,貌似是比谁设计的hash函数更坑黑客。
https://password-hashing.net/
我们来看看 PBKDF2 的代码实现,Bcrypt 和 Scrypt 虽然普遍认为比较吊,不过PBKDF2被用的更多,其概念无语言限制,安装下。
pip install passlib
接着
from passlib.hash import pbkdf2_sha256 hash = pbkdf2_sha256.encrypt("password", rounds=200000, salt_size=16)
偶们可以看到函数有三个参数,第一个 就是需要散列的字符串,第二个是密码的迭代次数,(难道说内部实现是 md5(md5(md5(password))),好吧这是我吐槽),通过设置第一个长度可以增加计算需要的时间,具体实际部署可以自行设定,越长越好,第三个是salt的大小。
核对时很简单,passlib有个函数用于验证是否正确
from passlib.hash import pbkdf2_sha256 pbkdf2_sha256.verify("password", hash)
Python库passlib: https://pythonhosted.org/passlib/
相关内容:
Mysql 漏洞利用(越权读取文件,实战怎么从低权限拿到root密码)
在申诉中猜想QQ密码可能明文储存,讨论腾讯申诉“历史密码”机制
QuarksPwDum导出2003 AD域控所有用户hash的方法
如何抵御社工库类的黑客攻击?在明文密码已泄露的情况下保护自己?
Base64 格式的密文,Base64 方式的 MD5 密匙,一些编码知识
Windows server 2012 用户hash抓取方法研究(本地+域)
如何碰撞两个功能不一样,但 MD5 值一样的程序的方法 + 源码公布
轻量级调试器神器 - mimikatz - 直接抓取 Windows 明文密码!
用 js 实现本地 md4、md5、sha1 加密表单并提交