ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【专题】Python加密模块hashlib的使用

2021-02-09 17:58:38  阅读:174  来源: 互联网

标签:hashlib password 加密 Python update md5 加密算法 MD5


Python加密模块hashlib的使用

一、加密算法介绍

  • 什么是加密算法呢?加密算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。
  • 加密算法就是通过加密算法f()对任意长度的数据data计算出固定长度的密文hexdigest,目的是为了发现原始数据是否被人篡改过。
  • 加密算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。

二、MD5加密算法

以常见的加密算法MD5为例,计算一个字符串的MD5值:

import hashlib

md5 = hashlib.md5()
# update函数的加密文本:英文必须是ASCII的二进制格式
md5.update(b'how are you?I fine, and you?')
print(md5.hexdigest())

输出结果:c61e87d5b1883b97428e02df773ba377

md5 = hashlib.md5()
# update函数如果不是ASCII格式,则必须对文字进行编码,否则会报错
md5.update("天王盖地虎".encode('utf-8'))
print(md5.hexdigest())

输出结果:151df4d2ddbdd1ad6a64c2c18b294828

统一上述的写法,将待加密的汉字或者英文content都可以直接先按照utf-8格式编码。即:

import hashlib

md5 = hashlib.md5()
content= input('请输入待加密的文本内容:')
md5.update(content.encode('utf-8'))
print(md5.hexdigest())

如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:

import hashlib

md5 = hashlib.md5()
md5.update(b'how are you?')
md5.update(b'I fine, and you?')
print(md5.hexdigest())

输出的结果也是c61e87d5b1883b97428e02df773ba377

可以看到和上面的加密结果一模一样。一般稍微改动一个字母或者字符,该算法计算出来的结果完全不同。MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。

三、sha1加密算法

除了MD5摘要算法外,比较常用的摘要算法还有SHA1,调用SHA1和调用MD5完全类似:

import hashlib

sha1 = hashlib.sha1()
sha1.update(b'how are you?')
sha1.update(b'I fine, and you?')
print(sha1.hexdigest())

输出结果:3782065e98449054afc40c8dc23de53778703982
SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。

有没有可能两个不同的数据通过某个加密算法得到了相同的密文?完全有可能,因为任何摘要算法都是把无限多的数据集合映射到一个有限的集合中。这种情况称为碰撞。

四、加密算法应用场景

任何允许用户登录的网站都会存储用户登录的用户名和密码。如何存储用户名和密码呢?方法是存到数据库表中:

usernamepassword
Chimu123456
TrainingLabc123
Daimaoabcdef

如果以明文保存用户密码,如果数据库泄露,所有用户的密码就落入黑客的手里。此外,网站运维人员是可以访问数据库的,也就是能获取到所有用户的密码。这样对用户信息或者数据而言是极不安全的,我们往往希望的是,只有用户自己知道自己的密码。

import hashlib

md5 = hashlib.md5()
password = input("待加密的明文密码:")
md5.update(password.encode('utf-8'))
print(md5.hexdigest())

在这里插入图片描述
正确的保存密码的方式是不存储用户的明文密码,而是存储用户密码的密文,比如MD5:

usernamepassword
Chimue10adc3949ba59abbe56e057f20f883e
TrainingLe99a18c428cb38d5f260853678922e03
Daimaoe80b5017098950fc58aad83c8c14978e
  • 当用户登录时,首先计算用户输入的明文密码的MD5,然后和数据库存储的MD5对比,如果一致,说明密码输入正确,如果不一致,密码肯定错误。
  • 存储MD5的好处是即使运维人员能访问数据库,也无法获知用户的明文口令。

设计一个验证用户登录的函数,根据用户输入的口令是否正确,返回True或False:

import hashlib

# 存储用户信息的数据表:db.user
db = {
    'Chimu':'e10adc3949ba59abbe56e057f20f883e',
    'TrainingL':'e99a18c428cb38d5f260853678922e03',
    'Daimao':'e80b5017098950fc58aad83c8c14978e'
}

def login(username,password):
    md5 = hashlib.md5()
    md5.update(password.encode('utf-8'))
    if username in db.keys():
        if md5.hexdigest() == db[username]:
            print("欢迎登陆!")
        else:
            print('密码错误,请重试!')
    else:
        print("用户不存在,先注册!")

username = input("请输入用户名:")
password = input("请输入密码:")
login(username,password)

运行效果截图:
在这里插入图片描述
由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:

经过Salt处理的MD5口令,只要Salt不被黑客知道,即使用户输入简单口令,也很难通过MD5反推明文口令。

将上述的加密验证需求改进之后如下:

import hashlib,random

def get_md5(s):
    return hashlib.md5(s.encode('utf-8')).hexdigest()
    
class User(object):
    def __init__(self,username,password):
        self.username = username
        self.salt = ''.join([chr(random.randint(48,122)) for i in range(20)])
        self.password = get_md5(password + self.salt)

db = {
    'chimu': User('michael', '123456'),
    'trainingl': User('bob', 'abc123'),
    'daimai': User('alice', 'abcdef')
}

def login(username,password):
    user = db[username]
    pwd = get_md5(password + user.salt)
    return user.password == pwd

print(login('bob',"abc999"))

五、小结

摘要算法在很多地方都有广泛的应用。要注意摘要算法不是加密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。

参考廖雪峰老师的Python教程

标签:hashlib,password,加密,Python,update,md5,加密算法,MD5
来源: https://blog.csdn.net/qq_41775769/article/details/113773615

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有