Python之hashlib模块使用方法

在Python中hashlib提供了Python的摘要算法,其可以对用户输入的敏感数据进行加密,可以达到不用存储用户输入的敏感信息,比如密码,业可以对文件进行校验,这些功能都可以通过hashlib模块轻松的完成。

python-hashlib

0x00 关于摘要算法

摘要算法是通过一系列的加密过程,并且不需要密钥,将任意长度的数据转化为一个长度固定的数据串,通常为16进制的字符串,该过程是不可逆的,只有输入相同的明文数据,经过相同的摘要算法才能得到一个相同的数据串。由于摘要算法不需要密钥的存在,因而适合用户分布式网络上使用。

0x01 Python中的摘要算法模块hashlib

由于政府法律规定,不得存储用户的密码(好像等于放屁一样的),因而只能通过摘要算法来判断用户是否输入正确的密码。当用户第一次设置密码后,通常会用摘要算法算出密码的数据串,因而将数据串存储与服务器上,用户下次输入时,再次通过摘要算法与数据库中的数据串进行对比来判断用户是否输入正确的密码。

import hashlib

md5 = hashlib.md5()
md5.update(b'xzymoe\'s blog')
print(md5.hexdigest())  #ff92e03cf67b9de9b9aaf1b40fe5a686

可以看出,如果密码是xzymoe’s blog的时候,其对应的唯一的数据串就是ff92e03cf67b9de9b9aaf1b40fe5a686,而理论上来说通过这个数据串是无法知晓用户的密码的(至于撞库的话,下面再说!)。

上面的代码可以看出,这里生成了一个md5对象,md5是最常见的摘要算法,速度快,生成的结果是固定的128bit字节,通常用一个32位的16进制字符串表示。md5的优点就是速度快,而伴随的缺点就是加密强度不是很强(当然足够用了,只是相对加密更强的sha256之类的算法来说)。需要注意的是更新(update)hash对象的时候只能使用byte类型

除了md5的方法为,Python的hashlib模块还提供了别的摘要算法,比如sha1、sha256、sha512等,其用法都是一样的,再来一个加密强的sha512来看看

import hashlib

sha512 = hashlib.sha512()
sha512.update(b'xzymoe\'s blog')
print(sha512.hexdigest())
#c88144abf1e7d5a3dd9312408de3f4827cf42fff4229b640e5084df78776b033015aa1de8d25d20face0b025e5d1356a6e3082d16f6a2aee61235b10668988f5

从结果上可以看出sha512的摘要算法明显强于md5,不过其缺点也很明显,算法复杂了,运算速度必然较慢。

0x02 摘要算法中的’加盐’

由于摘要算法是不可逆的,当你的md5被黑客拿到时候,黑客可以去一个庞大的md5库中对md5值进行对比,对于一些较弱密码的就容易被对比出来,从而‘撞库’。

比如,一些很简单的密码,比如你使用了简单的密码123456,黑客完全不用去破解摘要算法,可以通过常用的md5就对比出用户的密码来了。

import hashlib

md5 = hashlib.md5()
md5.update(b'123456')
print(md5.hexdigest())  #e10adc3949ba59abbe56e057f20f883e

如果md5为e10adc3949ba59abbe56e057f20f883e,那么很容易就被“猜到”。为了解决这种方法,因而需要在默认摘要算法的时候,添加一点佐料,就是俗称的加盐。

注意一下,加盐的时候也需要使用bytes类型。

import hashlib

md5 = hashlib.md5(b'salt')
md5.update(b'123456')
print(md5.hexdigest())  #f51703256a38e6bab3d9410a070c32ea
#不加盐的md5:e10adc3949ba59abbe56e057f20f883e

加盐后的好处是,即使很简单的密码,加盐后md5也会发生了改变,而加盐的内容,黑客又无法知道;当然如果遇到强大的黑客与弱智的管理员的话,管理员加盐内容也很容易被猜到,那么采取动态加盐,比如用用户名+123为‘盐’。

import hashlib

usrname = input('>>>')  #xzymoe
passwd = input('>>>')   #blog

md5 = hashlib.md5(usrname.encode())
md5.update(passwd.encode())
print(md5.hexdigest())  #d5de2906b0b9001399d0ac9d7d7d1a96

将用户名作为盐,而每个人的用户名都是不一样的,这样每个人的盐都不一样,加密效果会更好,这种方法被成为动态加盐。当然完全将用户名作为盐也不是一种明智的做法,这里只是举例,比如将用户名的前3位作为加盐的内容,可能比直接用用户名当盐效果更好。

0x03 摘要算法的其他

hashlib模块非常强大,当然其能发挥功力的地方不仅仅是上面的地方。hashlib还可以用与文件的校验,用迅雷的就知道了,当文件已经下载了100%的时候,最后迅雷会显示文件校验,就是对比本地文件与服务器上的文件的MD5是否相等。因而对于较大的文件可以进行分次的update。

import hashlib

md5 = hashlib.md5()
md5.update(b'xzymoexzymoexzymoe')
md5.update(b'blogblogblog')
print(md5.hexdigest())  #ba963470807439c8e8dad9672e1aade4

发表评论