hashlib模块

一、hash介绍

Hash,译做“散列”,也有直接音译为“哈希”的。把任意长度的输入,通过某种hash算法,变换成固定长度的输出,该输出就是散列值,也称摘要值。该算法就是哈希函数,也称摘要函数。

MD5是最常见的摘要算法,速度很快,生成结果是固定的16字节,通常用一个32位的16进制字符串表示。SHA1算法更安全点,它的结果是20字节长度,通常用一个40位的16进制字符串表示。而比SHA1更安全的算法是SHA256和SHA512等等,不过越安全的算法越慢,并且摘要长度更长。
hash是一类算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值, 该模块在用户登录认证方面应用广泛,对文本加密也很常见。

hash值的特点:

  1. 只要传入的内容一样,得到的hash值必然一样=====>要用明文传输密码文件完整性校验

  2. 不能由hash值返解成内容=======》把密码做成hash值,不应该在网络传输明文密码

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

hash的用途

用途1:特点II用于密码密文传输与验证
用途2:特点I、III用于文件完整性校验
hash算法就像一座工厂,工厂接收你送来的原材料(可以用m.update()为工厂运送原材料),经过加工返回的产品就是hash值

二、hash对象的方法

hash.update(arg)
更新hash对象。连续的调用该方法相当于连续的追加更新。例如m.update(a); m.update(b)相当于m.update(a+b)。注意,当数据规模较大的时候,Python的GIL在此时会解锁,用于提高计算速度。
一定要理解update()的作用,由于消息摘要是只针对当前状态产生的,所以每一次update后,再次计算hexdigest()的值都会不一样。
 
hash.digest()
返回bytes格式的消息摘要
 
hash.hexdigest()
与digest方法类似,不过返回的是两倍长度的字符串对象,所有的字符都是十六进制的数字。通常用于邮件传输或非二进制环境中。通常我们比较摘要时,比较的就是这个值!
 
hash.copy()
返回一个hash对象的拷贝
import hashlib 
m=hashlib.md5()# m=hashlib.sha256() 相当于制造工厂
m.update('hello'.encode('utf8'))  # 输入原料,原料必须是bytes类型
print(m.hexdigest())  #5d41402abc4b2a76b9719d911017c592
print(m.hexdigest())  #92a7e713c30abbb0319fa07da2a5c4af
 

验证传入值一样得到结果是否一致

 m2=hashlib.md5()
 m2.update('helloalvin'.encode('utf8'))
 print(m2.hexdigest()) #92a7e713c30abbb0319fa07da2a5c4af
注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样 但是update多次为校验大文件提供了可能。

以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。

1 import hashlib
2  
3 # ######## 256 ########
4  
5 hash = hashlib.sha256('898oaFs09f'.encode('utf8'))
6 hash.update('alvin'.encode('utf8'))
7 print (hash.hexdigest())#e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7

模拟撞库破解密码

import hashlib
passwds=[
    'alex3714',
    'alex1313',
    'alex94139413',
    'alex123456',
    '123456alex',
    'a123lex',
    ]
def make_passwd_dic(passwds):
    dic={}
    for passwd in passwds:
        m=hashlib.md5()
        m.update(passwd.encode('utf-8'))
        dic[passwd]=m.hexdigest()
    return dic

def break_code(cryptograph,passwd_dic):
    for k,v in passwd_dic.items():
        if v == cryptograph:
            print('密码是:%s' %k)

cryptograph='aee949757a2e698417463d47acac93df'
break_code(cryptograph,make_passwd_dic(passwds))

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

import hmac
h1=hmac.new('hello'.encode('utf-8'),digestmod='md5')
h1.update('world'.encode('utf-8'))

print(h1.hexdigest())
#要想保证hmac最终结果一致,必须保证:
#1:hmac.new括号内指定的初始key一样
#2:无论update多少次,校验的内容累加到一起是一样的内容


# 操作一
import hmac
h1=hmac.new('hello'.encode('utf-8'),digestmod='md5')
h1.update('world'.encode('utf-8'))

print(h1.hexdigest()) # 0e2564b7e100f034341ea477c23f283b

# 操作二
import hmac
h2=hmac.new('hello'.encode('utf-8'),digestmod='md5')
h2.update('w'.encode('utf-8'))
h2.update('orld'.encode('utf-8'))

print(h1.hexdigest()) # 0e2564b7e100f034341ea477c23f283b

三、使用场景

那么消息摘要有什么用呢?最常用的就是密码加密!密码加密不像数据加密,通常不需要反向解析出明文。而数据加密一般是需要反向解析的,我们无法从摘要反向解析出数据,加密是没问题了,但你让数据使用者如何获取数据?

现在,考虑下面的问题:

当用户登录时,首先计算用户输入的明文口令的摘要值,然后和数据库存储的摘要值进行对比。如果两者一致,说明口令输入正确,如果不一致,口令肯定错误。这样,不但数据库不用储存明文密码,即使能访问数据库的管理员“叛变”了,盗走了整个数据库,也无法获知用户的明文口令。

那么采用诸如MD5等消息摘要存储口令是否就一定安全呢?也不一定!假设你是一个黑客,已经拿到了存储MD5口令的数据库,如何通过MD5反推用户的明文口令呢?暴力破解?费事费力!,真正的黑客不会这么干。很多用户喜欢用123456,abcdef,loveyou这些简单的口令,由于MD5、SHA1等所有摘要算法都是公开的,黑客可以事先通过这些算法计算出这些常用口令的摘要值,得到一个反推表:

08b9239f92786f609443b669d5a041c1123456
960d15c50def228e8557d68945b5f7c0  : abcdef
47c0e829611b55cd05c680859adb8863  :loveyou

然后,无需暴力破解,只需要对比数据库的密码摘要,黑客就可以获得使用常用口令的用户账号。

加盐:额外给原始数据添加一点自定义的数据,使得生成的消息摘要不同于普通方式计算的摘要。

比如我下面给密码字符串“password”加上字符串“salt”,这里的“salt”字符串就是所谓的盐,其摘要值必然不等于正常摘要“password”字符串的值。当然这个“salt”具体是什么,完全可以自定义,而且不能告诉他人!千万不要以为加盐就是加个“salt”字符串。

md5 = hashlib.md5()
s = "password" + "salt"
md5.update(s.encode())
md5.hexdigest()

参考:https://blog.csdn.net/qq_42489308/article/details/89813925

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值