趣味学python(020)

关于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()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值