『Python』hashlib的简单使用

『Python』hashlib的简单使用hashlib的简单使用实用

大家好,又见面了,我是你们的朋友全栈君。

1. hashlib简介

1.1 什么叫hash

hash是一种算法(不同的hash算法只是复杂度不一样)(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值

1.2 hash值的特点(hash值/产品有三大特性):

  1. 只要传入的内容一样,得到的 hash 值必然一样

  2. 不能由 hash 值返解成内容

  3. 只要使用的 hash 算法不变,无论校验的内容有多大,得到的hash值长度是固定的

基于 1 和 3 可以做文件下载一致性的校验

基于 1 和 2 可以对用户密码进行加密

hash 算法就像一座工厂,工厂接收你送来的原材料,经过加工返回的产品就是hash值

2. hashlib使用

2.1 在进行md5哈希运算前,需要对数据进行编码,否则报错

import hashlib

obj = hashlib.md5()  # 构造一个hashlib的对象
obj.update("小马过河")  # update对指定字符串进行加密
print(obj)
TypeError: Unicode-objects must be encoded before hashing

2.2 obj是hash对象

import hashlib

obj = hashlib.md5()  # 构造一个hashlib的对象
obj.update("小马过河".encode(encoding='utf-8'))  # update对指定字符串进行加密
print(obj)
<md5 HASH object @ 0x000001C696DEF8F0>

2.3 加密的结果

import hashlib

obj = hashlib.md5()  # 构造一个hashlib的对象
obj.update("小马过河".encode(encoding='utf-8'))  # update对指定字符串进行加密
result=obj.hexdigest()
print(result)  # 24f67b0f6d02adc8867d612e0e0fc40a

2.4 给加密增添难度

import hashlib

obj = hashlib.md5("mcw@xiaoma@aaaafffff".encode("utf-8"))  # 添加一些内容,提高加密复杂度,此处的字符串也要先编码
obj.update("小马过河".encode(encoding='utf-8'))  # update对指定字符串进行加密
result = obj.hexdigest()
print(result)  # b11740508f28e04837f2c0e3a58cf990

2.5 用hashlib做成加密函数(添加基础的字符了的)

import hashlib

def get_md5(data):  # 传参为需要加密的字符串
    obj = hashlib.md5("sidrsicxwersdfsaersdfsdfresdy54436jgfdsjdxff123ad".encode('utf-8'))
    obj.update(data.encode('utf-8'))
    result = obj.hexdigest()
    return result

val = get_md5('123')

print(val)  # 35093270b6352fa9721370b781f7b4d7

3. 应用场景案例:用户账号密码登录,对明文密码进行加密

import hashlib

USER_LIST = []


def get_md5(data):
    obj = hashlib.md5("12:;idrsicxwersdfsaersdfsdfresdy54436jgfdsjdxff123ad".encode('utf-8'))
    obj.update(data.encode('utf-8'))
    result = obj.hexdigest()
    return result


def register():
    print('**************用户注册**************')
    while True:
        user = input('请输入用户名:')
        if user == 'N':
            return
        pwd = input('请输入密码:')
        temp = { 
   'username': user, 'password': get_md5(pwd)}
        USER_LIST.append(temp)


def login():
    print('**************用户登陆**************')
    user = input('请输入用户名:')
    pwd = input('请输入密码:')
    for item in USER_LIST:
        if item['username'] == user and item['password'] == get_md5(pwd):
            return True


if __name__ == '__main__':
    register()
    result = login()
    if result:
        print("登录成功")
    else:
        print("登陆失败")
**************用户注册**************
请输入用户名:>? ice
请输入密码:>? ice1314
请输入用户名:>? N
**************用户登陆**************
请输入用户名:>? ice
请输入密码:>? ice1314
登录成功
**************用户注册**************
请输入用户名:>? ice
请输入密码:>? ice1314
请输入用户名:>? N
**************用户登陆**************
请输入用户名:>? ice
请输入密码:>? ice520
登陆失败

3.1用户登录场景分析

  1. 用户登录需要使用密码,密码一定要加密,保证用户的信息安全。
    • 加密可以使用 hashlib 模块进行加密。
    • 加密可以写成加密函数
    • 提高密码解密的复杂性,代码中多加字符串。(加密算法虽然依然非常厉害,但是也存在缺陷,即:通过 hash 碰撞可以反解。所以,有必要对加密算法中添加自定义 key 再来做加密。)
  2. 用户注册写成用户注册的函数,用户登录写成用户登录的函数。
  3. 先执行用户注册的函数,再执行用户登录的函数
  4. 注册与登录需要交互,用到input函数接收用户输入
  5. 如果用户注册和用户登录用到死循环,那么就要判断用什么来终止循环(比如这里是输入N)
  6. 用户注册提交的密码加密的密文写入数据库。、用户注册提交的密码加密的密文写入数据库。
  7. 用户登录输入的密码,使用相同加密函数加密后与数据库密文比对,相等就登录,否则就失败
  8. 登录的本质是判断从用户接收的加密后密文和注册时存入数据库的密文对比,用户名密文对比成功,则继续往下执行登录后的操作。
  9. 用户输入密码要防止旁人看到,可以使用getpass模块
  10. 与密码相关的很重要,一定要加密。包括自己拥有的影响大的重要数据也要加密,防止黑客入侵获取而泄密。

4. 校验文件的一致性

如何保证下载的文件过程中不丢包,保证下载数据的完整性

r""" 文件一致校验 可以拷贝一个文件放在两个不同的盘中,然后通过判断两个文件的hash值是否相等,判断两个文件是否是同一个文件 """

import hashlib

m = hashlib.md5()
n = hashlib.md5()

with open(r'file1', 'rb') as f:
    for line in f:
        m.update(line)
	print(m.hexdigest())

with open(r'file2', 'rb') as f:
    for line in f:
        n.update(line)
	print(n.hexdigest())

5. 破解用户注册的密码

r"""模拟撞库破解密码"""
import hashlib

passwords = [  # 可以通过random实现对passwords中的内容
    'alex3714',
    'alex1313',
    'alex94139413',
    'alex123456',
    '123456alex',
    'a123lex',
]


def make_passwd_dic(pwds):  # 通过明文密码列表,造出与之对应的hash值得字典
    dic = { 
   }
    for password in pwds:
        m = hashlib.md5()  # 使用md5算法,造了一个工厂
        m.update(password.encode('utf-8'))  # 给工厂运送原材料(即我们要加密的内容)
        dic[password] = m.hexdigest()  # 产出hash值(即最终的产品),将其加入到我们事先造好的空字典中,字典形式:{密码:hash值}
    return dic


def break_code(cryptograph, passwd_dic):  # 判断拦截的hash值是否与字典中事先造好的hash值相等,相等则说明成功进行破解
    for k, v in passwd_dic.items():
        if v == cryptograph:
            print('密码是===>3[46m%s3[0m' % k)


pwd = 'aee949757a2e698417463d47acac93df'  # 我们拦截拿到的密码,经过加密的hash值

break_code(pwd, make_passwd_dic(passwords))  # 将要破解的密码hash值,和事先造好的hash的字典当做函数的实参传给对应的形参

6. hmac模块的加密方式

与hashlib类似,好像是先加密一次,然后对加密的结果加前缀字符串,再用一个加密方法再次加密

r"""python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密"""

import hmac

h = hmac.new(key=b"secret", msg='天王盖地虎'.encode('utf8'), digestmod='MD5')
h.update('hello'.encode('utf8'))
print(h.hexdigest())  # db78538167de0b25b7fcd88bdcde3db9

r""" 要想保证hmac最终结果一致,必须保证: 1: hmac.new括号内指定的初始key一样 2: 无论update多少次,校验的内容累加到一起是一样的内容 下面单重方式得到的结果是一样的 """

h1 = hmac.new(key=b'tom', digestmod='MD5')  # 初始值必须保证一致,最终得到的结果就会不一样
h1.update(b'hello')
h1.update(b'world')
print(h1.hexdigest())  # 0426ccec3b134e8c18fdcefee841ef25

h2 = hmac.new(key=b'tom', digestmod='MD5')  # 初始值必须保证一致,最终得到的结果就会不一样
h2.update(b'helloworld')
print(h2.hexdigest())  # 0426ccec3b134e8c18fdcefee841ef25

h3 = hmac.new(key=b'tomhelloworld', digestmod='MD5')  # 初始值不一样,所以与上面两种的结果不一样
print(h3.hexdigest())  # ff1214d895bbaf5f1847db4ebae8212e
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/133107.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • CentOS7中关闭firewall,并使用iptables管理防火墙

    CentOS7中关闭firewall,并使用iptables管理防火墙

    2021年10月19日
  • 中间件技术及双十一实践·EagleEye篇「建议收藏」

    中间件技术及双十一实践·EagleEye篇「建议收藏」EagleEye——分布式调用的跟踪者转自:http://www.tuicool.com/articles/fuYz2i综述阿里巴巴电子商务平台现在是一个由很多个应用集群组成的非常复杂的分布式系统。这些应用里面主要有处理用户请求的前端系统和有提供服务的后端系统等,各个应用之间一般有RPC调用和异步消息通讯两种手段,RPC调用会产生一层调一层的嵌套,一个消息发布出来更会被多

  • SAP Transaction Code

    SAP Transaction Code[@more@]F-01EnterSampleDocumentF-02EnterG/LAccountPostingF-03ClearG/LAccountF-04PostwithClearingF…

  • java技术介绍_Java技术汇总

    java技术介绍_Java技术汇总这篇文章总结了多年来使用Java的一些心得体会,主要是和一些Java基础知识点相关的,也希望能分享给刚刚入门的Java程序员和打算入Java开发这个行业的准新手们,希望可以给大家一些经验,能让大家更好学习和使用Java。这次介绍的主要内容是和J2SE相关的部分,经过这么多年的Java开发,以及结合平时面试Java开发者的一些经验,J2SE方面主要就是要掌握以下的一些内容。1.JVM相关(包括了…

  • stm32f103c8t6数据手册「建议收藏」

    stm32f103c8t6数据手册「建议收藏」STM32F103ZET6(中文)-豆丁网(docin.com)https://www.docin.com/p-304006862.html?docfrom=rrela

    2022年10月15日
  • service mesh框架对比_k8s containerd

    service mesh框架对比_k8s containerdservice用于4层路由负载 ingress用于7层路由负载1 Service介绍在kubernetes中,Pod是应用程序的载体,我们可以通过Pod的IP来访问应用程序,但是Pod的IP地址不是固定的,这就意味着不方便直接采用Pod的IP对服务进行访问。为了解决这个问题,kubernetes提供了Service资源,Service会对提供同一个服务的多个Pod进行聚合,并且提供一个统一的入口地址,通过访问Service的入口地址就能访问到后面的Pod服务。Service在很多情况下只是一个概念

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号