28 hashlib模块 -----摘要算法的模块

  • 能够把 一个 字符串 数据类型的变量
  • 转换成一个 定长的 密文的 字符串,字符串里的每一个字符都是一个十六进制数字对于同一个字符串,不管这个字符串有多长,只要是相同的,无论在任何环境下,
  • 多少次执行,在任何语言中使用相同的算法\相同的手段得到的结果永远是相同的只要不是相同的字符串,得到的结果一定不同

有啥用?
可以把账号密码转换城密文 存储到数据库里,就很安全了
例如:
 'zhuangdd3714'   -> '127649364964908724afd'

字符串 --> 密文
密文还能转化成字符串吗? 不行啊! 不可逆的

1234567 - > '127649364964908724afd'
算法 : 对于同一个字符串,用相同的算法,相同的手段去进行摘要,获得的值总是相同的!
1234567   摘要- > '127649364964908724afd'   用后面这个密文与数据库存储的密文作比较,相同即可

2、可以校验下载的文件是否完整,可用?
  下载前的MD5 = 下载后的MD5 即达成一致性
一、md5
  md5是一个算法,32位的字符串,每个字符都是一个十六进制
    md5算法 效率快 算法相对简单
update
hexdigest
s1 = 'zhuangdd3714'  # aee949757a2e698417463d47acac93df


md5_obj = hashlib.md5()
md5_obj.update(s1.encode('utf-8'))    # 必须传入Bytes 作为参数 b'参数'
res = md5_obj.hexdigest()    # 获得摘要结果
print(res, len(res), type(res))   # aee949757a2e698417463d47acac93df 32 <class 'str'>
二、sha1 
  sha1也是一个算法,转换为40位的字符串,每个字符都是一个十六进制
      算法相对复杂 计算速度也慢(用的人少,相对安全?)

把上面的md5 换成sha1就行
s1 = 'zhuangdd3714'
md5_obj = hashlib.sha1()
md5_obj.update(s1.encode('utf-8'))
res = md5_obj.hexdigest()
print(res,len(res),type(res))


__________________
a8eabf4a67b6c37941186b8fd1000eb6b92d3147 40 <class 'str'>

三、安全性

  撞库

    大白话讲就是创建一个海量数据库,创建一些常用的密码,用同样的算法,例如用的比较多的md5摘要这些密码,然后把生成的密文与要破解的账号密码数据库

做比较分析,从而达到破解密码的奇效。

所以仅仅用密文模块来加密远远不够呀,那怎么办呢?

加盐!
  也就是在实例化对象的时候,我们传入盐这个参数

加盐!
s1 = 'zhuangdd3714'


md5_obj1 = hashlib.md5('任意的字符串作为盐'.encode('utf-8'))
md5_obj1.update(s1.encode('utf-8'))
res = md5_obj1.hexdigest()
print(res,len(res),type(res))
#结果是437c55d3563c457dcb0215b348561cd2 32 <class 'str'>

不加盐

md5_obj = hashlib.md5()
md5_obj.update(s1.encode('utf-8'))
res = md5_obj.hexdigest()
print(res,len(res),type(res))
# 33b2ce1064ab66aa329715a825dd0b7f 32 <class 'str'>

两者结果是不同的!这样安全性提高 了~   但是还是不够的呀

固定的盐,还是会被破解的,只要数量达到一定规模,还是会被分析出来

那怎么办?

动态加盐!

username = input('username : ')
passwd = input('password : ')
md5obj = hashlib.md5(username.encode('utf-8'))
md5obj.update(passwd.encode('utf-8'))
print(md5obj.hexdigest())
# ee838c58e5bb3c9e687065edd0ec454f

是的,这里用了用户账号名来当作盐,由于每个用户的账号名都是不同的! 所以这里安全性大大提高了!

四、文件的一致性校验

md5_obj = hashlib.md5()
with open('5.序列化模块_shelve.py','rb') as f:
    md5_obj.update(f.read())
    ret1 = md5_obj.hexdigest()

md5_obj = hashlib.md5()   # 这里注意要再实例化一次
with open('5.序列化模块_shelve.py.bak','rb') as f:
    md5_obj.update(f.read())
    ret2 = md5_obj.hexdigest()
print(ret1,ret2)

===================
最后ret1 ==ret2  证明两个文件内同一致

大文件的校验

假如文件10G 你的内存只有4G 所以无法一次性update 摘要

所以考虑拆开摘要

例如:

md5_obj = hashlib.md5()
md5_obj.update('hello,world'.encode('utf-8'))
print(md5_obj.hexdigest())

md5_obj = hashlib.md5()
md5_obj.update('hello,'.encode('utf-8'))
md5_obj.update('world'.encode('utf-8'))
print(md5_obj.hexdigest())

================
结果一致

所以大文件的已执行校验:
md5_obj = hashlib.md5()
with open('5.序列化模块_shelve.py.bak','rb') as f:
    md5_obj.update(f.read())
    # 循环 循环的读取文件内容
    # 循环的来update
print(md5_obj.hexdigest())

小试牛刀?

写成一个函数
参数 : 文件1的路径,文件2的路径,默认参数 = 1024000
计算这两个文件的md5值
返回它们的一致性结果 T/F




猜你喜欢

转载自www.cnblogs.com/zhuangdd/p/12657114.html