Python的hashlib提供常见的摘要算法,如MD5,SHA1等等。
摘要算法是什么?摘要算法又称哈希算法和散列算法。它将任何长度的数据转换为固定长度的数据串(通常用16进制字符串表示)。
摘要算法是通过摘要函数f()任何长度的数据data计算固定长度的摘要digest,目的是找出原始数据是否被篡改。
摘要算法之所以能指出数据是否被篡改,是因为摘要函数是单向函数f(data)但是通过很容易digest反推data但是很难。而且,制作原始数据。bit所有的修改都会导致计算出的摘要完全不同。
我们使用常见的摘要算法MD例如,计算一个字符串MD5值:
import hashlib md5 = hashlib.md5() md5.update('how to use md5 in python hashlib?') print md5.hexdigest() 计算结果如下: d26a53750bc40b38b65a520292f69306
如果数据量很大,可以次调用update(),最后计算的结果是一样的:
md5 = hashlib.md5() md5.update('how to use md5 in ') md5.update('python hashlib?') print md5.hexdigest()
MD5是最常见的摘要算法,速度快,产生固定的128 bit字节通常用32位16进制字符串表示。另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:
import hashlib sha1 = hashlib.sha1() sha1.update('how to use sha1 in ') sha1.update('python hashlib?') print sha1.hexdigest()
SHA1的结果是160 bit字节通常用40位16进制字符串表示。SHA更安全的算法是SHA256和SHA512,但算法越安全越慢,摘要长度越长。
摘要算法应用
任何允许用户登录的网站都会存储用户登录的用户名和密码。如何存储用户名和密码?方法是存储在数据库表中:
username | pwd |
lily | 123 |
susan | 1qi34 |
kevin | e4678 |
如果用户密码保存在明文中,如果数据库泄露,所有用户密码都将落入黑客手中。此外,网站运维人员可以访问数据库,即获得所有用户的密码。保存密码的正确方法是不存储用户的密码,而是存储用户密码的摘要,如MD5:
username | pwd |
lily | 202cb962ac59075b964b07152d234b70 |
susan | e5d6cf137f878baea1d7edd2430b2151 |
kevin | b0b91cecf47eae95de14bd51407c9031 |
import hashlib md5 = hashlib.md5() # md5.update(b'123') # print(md5) # <md5 HASH object @ 0x000002812EA166D0> # res = md5.hexdigest() # print(res) # 202cb962ac59075b964b07152d234b70 # md5.update(b'1qi34') # res = md5.hexdigest() # print(res) # e5d6cf137f878baea1d7edd2430b2151 md5.update(b'e4678') res = md5.hexdigest() print(res) # b0b91cecf47eae95de14bd51407c9031
考虑到这种情况,许多用户喜欢使用1234568,password这些简单的密码提前计算出这些简单的密码MD5值,得到反推表:
'e10adc3949ba59abbe56e057f20f883e': '123456' '21218cca77804d2ba1922c33e0151105': '888888' '5f4dcc3b5aa765d61d8327deb882cf99': 'password'
这样就不需要破解,只需要比较数据库MD5.黑客获得了使用常用密码的用户账户。
当然,对于用户来说,不要使用太简单的密码。但是,我们能加强对程序设计中简单密码的保护吗?
因为常用的密码MD5值很容易计算,所以要保证存储的用户密码不是已经计算出来的常用密码。MD5.这种方法是通过在原始密码上添加一个复杂的字符串来实现的,俗称加盐:
hashlib.md5("salt".encode("utf8"))
经过Salt处理的MD5口令,只要Salt即使用户输入简单的密码,也很难通过MD5反推明文口令。
但是,如果两个用户使用相同的简单密码,如123456,他们将在数据库中存储两个相同的密码MD5值,说明这两个用户的密码是一样的。有没有办法让使用相同密码的用户存储不同的密码?MD5呢?
假设用户无法修改登录名,可以将登录名作为登录名Salt计算的部分MD5.实现相同密码的用户也存储不同的密码MD5。
摘要算法在很多地方都有广泛的应用。要注意摘要算法不是加密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口.