hashlib
Python的hashlib模块提供了常见的摘要算法。
摘要算法,又称哈希算法(hash算法)。它通过一个摘要函数f( )
把任意长度的数据date
转化为一个固定长度的摘要digest
。
摘要算法不能用来加密,因为它可以简单地转化一个数据,但却很难进行反转化。可以说摘要算法是单向的,而且更改数据其中的一个bit都会让转化结果完全不一样。
常见的摘要算法有MD5,SHA1等,摘要算法主要应用于储存用户登录的用户名与密码。
任何允许用户登录的网站都会把用户的用户名与密码储存到数据库中,如果以明文储存,一旦数据库泄露则会泄露用户的隐私,而且网站运维人员本身也不应该知道用户的密码。
所以,一般而言,都是储存用户密码的摘要,即通过摘要算法处理之后再储存。
当用户登录时,输入的密码先通过摘要算法转化,如果与之前储存的密码摘要一致,则通过验证。
hmac加盐
采用摘要算法储存密码就一定安全了吗?其实不然。一些黑客先储存一些常用的简单密码的摘要,一旦匹配到,就能反推回去,像123这种密码:
密码 | 对应MD5值 |
---|---|
123 | 202cb962ac59075b964b07152d234b70 |
123456 | e10adc3949ba59abbe56e057f20f883e |
或许你已经想到了,要解决这个问题,只要对原始的密码加一个复杂的字符串,再进行转化即可,这个过程俗称“加盐”
我们可以用用户特定的数据资料作为盐Salt,比如登录名(假设登录名不可修改)等。
import hmac, hashlib
userdict = {}
def new_user():
username = input("Pls input your username:>>>").strip()
password = input("Pls input your password:>>>").strip()
password = hashlib.new('sha256',password.encode('utf-8')).hexdigest()
if username not in userdict:
userdict[username] = password
print(f'add {username} ok!')
else:
print('username exist!')
def login_user(username,password):
passwd = hashlib.new('sha256',password.encode('utf-8')).hexdigest()
temp = hmac.new(username.encode('utf-8'),passwd.encode('utf-8')).digest()
strs = hmac.new(username.encode('utf-8'),userdict.get(username,'I got no username!!!').encode('utf-8')).digest()
return hmac.compare_digest(temp,strs)
试验一下:
new_user()
======================================
Pls input your username:>>>hello kitty
Pls input your password:>>>iamtiger!
add hello kitty ok!
userdict
======================================
{'hello kitty': '037cc5cbc5ca6a441ed5570892c3354d07ef53e638c1531184c307a706b6eb67'}
login_user('hello kitty','iamtiger!')
======================================
True
login_user('hello kitty','iamtiger')
======================================
False