关于md5加密密码,登录认证
最近,小编刚好在学习数据库,刚巧又了解到了hashlib模块,在初步了解关于网站的登录问题之后,心血来潮,自己写了一段代码用于检测用户登录验证问题。
首先。先来说说,网站的用户登录问题。对于一个网站来说,用户需要注册用户名,这就需要网站去存储这些数据,一边用户下次登录时得以比较。
因为涉及到隐私的问题,所以,如果密码泄露的话,会造成分非常不好的影响。当然,这其中也涉及到网站维护人员,如果不对密码做处理的话,后台维护人员将会轻而一举的指导用户的隐私。
一般来说,最常用到的就是md5摘要算法(摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。),但它不能用来做加密算法,因为它是单项加密,几乎不能依据密文退出明文是什么。
MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。另一种常见的摘要算法是SHA1,SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。
比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。
```python
import hashlib
md5 = hashlib.md5()
md5.update('how to use md5 in python hashlib?')
print md5.hexdigest()
在网站中,数据一般存储在数据库中,对于用户名,密码这样规整的数据,存储在MySQL中最适合不过了。
正确的保存口令的方式是不存储用户的明文口令,而是存储用户口令的摘要,比如MD5:
username | password
---------+---------------------------------
michael | e10adc3949ba59abbe56e057f20f883e
bob | 878ef96e86145580c38c87f0410ad153
alice | 99b1c2188db85afee403b1536010c2c9
HASH
散列函数,一般翻译为哈希,把输入的任意长度的数据,通过散列函数进行转化,变成一个长度固定的值,基本
唯一的。
这样经过md5加密的数据就会得到保留,等用户下次登陆的时候,对密码做同样的加密,在与原密码进行比较就行。
有以下几个特点:
不可逆
定长输出
抗修改行
强碰撞性
考虑这么个情况,很多用户喜欢用123456,888888,password这些简单的口令,于是,黑客可以事先计算出这些常用口令的MD5值,得到一个反推表:
'e10adc3949ba59abbe56e057f20f883e': '123456'
'21218cca77804d2ba1922c33e0151105': '888888'
'5f4dcc3b5aa765d61d8327deb882cf99': 'password'
黑客常用的彩虹表可以达到100G,在运用数据查询功能就能破解一些简单的密码。
所以,一般来说,还要进行 “加盐” 操作。这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:
def calc_md5(password):
return get_md5(password + 'the-Salt')
如下图:
一般来说,通过常用的或者干脆利用随机产生的字母来组成salt。
这里用到了列表表达式:
salt = ''.join([chr(random.randint(48, 122)) for i in range(20)])
join真的很好用的,可以将元组变成字符串,而str却做不到。
话不多说,
需要先导入模块:
MySQL相比于MongoDB和redis来说,存储这个最合适不过了。
import hashlib
import pymysql
import random
下面来配置一些连接MySQL的参数:
db_config = {
'user': 'root',
'password': 'qwe123',
'db': 'stu',
'charset': 'utf8'
}
小编的思路大致是这样的,先构造一个函数login用于注册用户,将用户名和密码记录到数据库中。
关于MySQL的操作,小编不做叙述。
def login(user, password):
conn = pymysql.connect(**db_config)
# 建立游标
dbs = conn.cursor()
salt = ''.join([chr(random.randint(48, 122)) for i in range(20)])
# print(salt)
sentence = "insert into stu value('%s', '%s', '%s')" % (user, password, salt)
# print(sentence)
dbs.execute(sentence)
print('用户注册成功!!!!')
dbs.close()
conn.commit()
return 0
小编将用于登录验证的函数做了一个封装,将它封装在一个Compute当中。
下面时初始化:
class Compute():
def __init__(self, user, password):
self.user = user
self.password = password
# 连接数据库,展示相应的user用户名
self.conn = pymysql.connect(**db_config)
self.salt = ""
# 建立游标
self.dbs = self.conn.cursor()
# 产生一个列表用来存储用户名的数据
self.list_user = []
# a.salt是注册时封装好的盐,这时是固定的盐,所以只要账号密码对了就可以了。
# self.salt = ''.join([chr(random.randint(48, 122)) for i in range(20)])
在定义一个用于显示所有用户名的函数,用于提示用户(当然,也是方便小编进行调试)。
def display(self):
# 展示数据库中的用户名
print('数据库中的用户名:')
self.dbs.execute('select user from stu')
for user in self.dbs.fetchall():
user1 = ''.join(map(str, user))
self.list_user.append(user1)
print(user1)
print('----------------------------------')
定义一个计算md5加密的函数,用于进行对密码的单项加密:
ef calculate(self):
md5 = hashlib.md5()
md5.update((self.password + self.salt).encode())
answer = md5.hexdigest()
# print(md5.hexdigest())
return answer
下面在来分享一下其他的类型的加密:
def sha_1(self):
res = hashlib.new('sha1', (self.password + self.salt).encode('utf-8'))
answer = res.hexdigest()
print(res.hexdigest())
return answer
def sha_256(self):
res = hashlib.sha256((self.password + self.salt).encode())
answer = res.hexdigest()
print(res.hexdigest())
return answer
接着写检验密码的代码:
def examine_md5(self):
# print(self.user, self.list_user)
if self.user in self.list_user:
sentence1 = "select password from stu where user = '{}'".format(self.user)
print('you are the user.')
sentence = "select salt from stu where user = '{}'".format(self.user)
# 拿出数据库中的密码
self.dbs.execute(sentence1)
password = ''.join(map(str, self.dbs.fetchone()))
# 获取数据库中的 salt
self.dbs.execute(sentence)
salt = ''.join(map(str, self.dbs.fetchone()))
self.salt = salt
self.conn.commit()
# 对数据建库中的密码进行加密
md5 = hashlib.md5()
md5.update((password + salt).encode('utf-8'))
pri_password = md5.hexdigest()
if pri_password == self.calculate():
print('you are right,then you pass through the checkout!!!')
else:
print('wrong password!!')
else:
print("it hasn't the user,please assure the user. ")
很高兴能够分享给大家,如有更好的思路,也请告知我哦!!!!!😁😁😁😁😁
最后小编附上 全部代码:
import hashlib
import pymysql
import random
db_config = {
'user': 'root',
'password': 'qwe123',
'db': 'stu',
'charset': 'utf8'
}
def login(user, password):
conn = pymysql.connect(**db_config)
# 建立游标
dbs = conn.cursor()
salt = ''.join([chr(random.randint(48, 122)) for i in range(20)])
# print(salt)
sentence = "insert into stu value('%s', '%s', '%s')" % (user, password, salt)
# print(sentence)
dbs.execute(sentence)
print('用户注册成功!!!!')
dbs.close()
conn.commit()
return 0
class Compute():
def __init__(self, user, password):
self.user = user
self.password = password
# 连接数据库,展示相应的user用户名
self.conn = pymysql.connect(**db_config)
self.salt = ""
# 建立游标
self.dbs = self.conn.cursor()
# 产生一个列表用来存储用户名的数据
self.list_user = []
# a.salt是注册时封装好的盐,这时是固定的盐,所以只要账号密码对了就可以了。
# self.salt = ''.join([chr(random.randint(48, 122)) for i in range(20)])
def display(self):
# 展示数据库中的用户名
print('数据库中的用户名:')
self.dbs.execute('select user from stu')
for user in self.dbs.fetchall():
user1 = ''.join(map(str, user))
self.list_user.append(user1)
print(user1)
print('----------------------------------')
def calculate(self):
md5 = hashlib.md5()
md5.update((self.password + self.salt).encode())
answer = md5.hexdigest()
# print(md5.hexdigest())
return answer
def sha_1(self):
res = hashlib.new('sha1', (self.password + self.salt).encode('utf-8'))
answer = res.hexdigest()
print(res.hexdigest())
return answer
def sha_256(self):
res = hashlib.sha256((self.password + self.salt).encode())
answer = res.hexdigest()
print(res.hexdigest())
return answer
def examine_md5(self):
# print(self.user, self.list_user)
if self.user in self.list_user:
sentence1 = "select password from stu where user = '{}'".format(self.user)
print('you are the user.')
sentence = "select salt from stu where user = '{}'".format(self.user)
# 拿出数据库中的密码
self.dbs.execute(sentence1)
password = ''.join(map(str, self.dbs.fetchone()))
# 获取数据库中的 salt
self.dbs.execute(sentence)
salt = ''.join(map(str, self.dbs.fetchone()))
self.salt = salt
self.conn.commit()
# 对数据建库中的密码进行加密
md5 = hashlib.md5()
md5.update((password + salt).encode('utf-8'))
pri_password = md5.hexdigest()
if pri_password == self.calculate():
print('you are right,then you pass through the checkout!!!')
else:
print('wrong password!!')
else:
print("it hasn't the user,please assure the user. ")
if __name__ == '__main__':
# user = input('please input the user name:')
# password = input("please input the password:")
# login(user, password)
a = Compute('Big_ben', '123456')
a.display()
a.examine_md5()