49 hashlib 与 hmac 模块

483次阅读
没有评论

共计 4849 个字符,预计需要花费 13 分钟才能阅读完成。

一. 引入

1. 什么是算法

  • 算法就是高效解决问题的方法
  • 一种算法就是用来解决一种特定问题的
比如从 10000 个从小到大排列且不连续数字里找出 8654
普通方法就是用眼瞅, 从左到右
运气好瞅一次, 运气不好瞅一万次
于是就有了二分法, 取出中间的值
左边的值一定比中间的值小
右边的值一定比中间的值大
于是找到 8654 所用的时间大大缩短

2.hash 哈希算法

可以把把文本内容 / 一串字符计算成一串 hash

一串内容 ---->"hash" 算法 ---->"hash" 值
  • md5

  • sha512

  • sha256

3.hash 值的三大特点

  • 传入的内容一样, 采用的 hash 算法一样, 得到的 hash 值也一定一样
  • hash 不可逆推, 不能通过 hash 值反推出明文
  • hash 值的长度取决于采用的 hash 算法, 与传入的内容多少无关

4. 哈希的应用

  • 结合特点 12 可以用于加密
  • 结合特点 13 可以用于文件完整性校验
再网页上下载文件进度条 100% 后会卡一小些时间
其实就是在进行 "hash" 的校验

5. 密码加盐

  • 客户端向服务端提交密码会在客户端先通过算法加密
  • 而服务端存有加密后的密码, 直接比对进行校验
  • 但是这还是不够安全的, 高技术的黑客可以拿着密文密码进行撞库或者写客户端直接提交截获到的密文
  • 于是就出现了 密码加盐 的概念
⛅密码加盐相当于暗号, 只有设置者知道
⛅示范:
    正常密码: 123456
    加盐密码: 派大星 123456 海绵宝宝
        或者: 章 1 鱼 2 哥 3 蟹 4 老 5 板 6
⛅加盐之后计算出来的 "hash" 是完全不一样的
⛅想要撞库的人就必须要猜到使用的算法和加的盐

一.hashlib 模块介绍

1. 什么是 hashlib 模块

  • hashlibPython的内置模块
  • 它为我们提供了多种安全的摘要方法

2.hashlib 模块的作用

  • 目前在大部分操作系统下, hashlib模块支持md5(),sha1(), sha224(), sha256(), sha384(), sha512(), blake2b().... 等多种hash 构造方法
  • 这些构造方法在使用上通用, 返回带有同样接口的 hash 对象, 差别只在于构造方法的选择, 也就是对算法的选择
  • 得到对象后可以使用通用的 update() 方法将 bytes 类型 的数据添加到对象里,最后通过digest()(bytes 摘要) 或者hexdigest()(十六进制摘要) 方法获得当前的摘要
🍓 "hashlib" 模块所支持的算法
__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
                      'blake2b', 'blake2s',
                      'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
                      'shake_128', 'shake_256')

ps : update()方法现在只接受 bytes 类型的数据,不接收 str 类型

二.hashlib 模块的使用

1. 放入原材料, 得到摘要

import hashlib

# m = hashlib.sha512()
m = hashlib.md5()  # 还有其他算法 "sha256()" 等等
m.update("helloword".encode("utf-8"))
res = m.hexdigest()
print(type(res))  # <class 'str'>
print(res)        # 59284aa85709ddaf3bd246030060f6a2

2. 将原材料分多次 update()

  • 把一段很长的数据 update 多次, 与一次 update 这段长度的数据,得到的结果一样, 但是 update 多次为校验大文件提供了可能
import hashlib

# m = hashlib.sha512()
m = hashlib.md5()  # 还有其他算法 "sha256()" 等等
m.update("he".encode("utf-8"))
m.update("llo".encode("utf-8"))
m.update("word".encode("utf-8"))
res = m.hexdigest()
print(res)        # 59284aa85709ddaf3bd246030060f6a2

3. 密码加盐

  • 以上加密算法虽然非常安全, 但有时候存在缺陷, 黑客通过 撞库 可以反解, 所以, 有必要对加密算法中添加自定义 key 再来做加密
import hashlib

🍓没加盐
m = hashlib.sha256()
m.update("helloword".encode("utf-8"))
res = m.hexdigest()
print(res)  # 0b322d15ea034793a8646baa1744ffacbdf7f959b66c68970f032c4ac8b9c8cb

🍓密码加盐
salt = " 我是盐 "
m = hashlib.sha256()
m.update("helloword".encode("utf-8"))
m.update(salt.encode("utf-8"))
res = m.hexdigest()
print(res)  # c3527c3cf2592303ed2e616772c6f5409e7ab4a40c2f49cb8c16647abc0048ac

可以发现两种结果完全不同, 加的盐只有你自己知道, 那么被破解的几率就大大降低了

三.hmac 模块

1. 什么是 hmac 模块

  • hmac 模块也是 Python 的内置模块
  • 它内部采用了 key 对应 内容 的方式进行进一步的加密方式

2. 保证 hmac 结果一致

  • 必须保证 hmac.new() 括号内指定的初始 key 相同
  • 无论 update 多少次, 校验的内容累加一起必须一样

3.hmac 的使用

  • 加密内容一次 update
import hmac

h = hmac.new("init_key".encode("utf-8"),digestmod="md5")
h.update("helloword".encode("utf-8"))
res = h.hexdigest()
print(res)  # 7c221a51ee6e0d36a1a8b07d7948bc0c
  • 加密内容多次 update
h = hmac.new("init_key".encode("utf-8"),digestmod="md5")
h.update("he".encode("utf-8"))
h.update("llo".encode("utf-8"))
h.update("word".encode("utf-8"))
res = h.hexdigest()
print(res)  # 7c221a51ee6e0d36a1a8b07d7948bc0c

我們可以发现摘要值结果一样

  • 将初始 key 更换, 加密内容不变
h = hmac.new("neq_key".encode("utf-8"),digestmod="md5")
h.update("helloword".encode("utf-8"))
res = h.hexdigest()
print(res)  # 200e7722b5842e83851955e20dabb6e8

可以发现摘要值已经变化了

小结 :

​ 使用 hmac 算法比标准 hash 算法更安全,因为针对相同的加密内容,不同的 key 会产生不同的hash

三. 暴力破解

49 hashlib 与 hmac 模块

什么是暴力破解? 其实就是乱猜. 暴力破解其实是通过循环的方式进行对比, 我们都知道加密算法是不可逆的, 比如 MD5 算法, 那么网上那些所谓的 MD5 解密网站是怎么做到的呢? 其实使用的就是这种原理.

撞库的原理也差不多 : 简单来说,撞库就是黑客利用已经泄露的账号密码,去其他网站或应用程序中尝试登录的行为。撞库主要利用的是人们在多个平台使用相同账号密码的行为习惯

import hashlib

m = hashlib.md5()
m.update("123".encode("utf-8"))
print(m.hexdigest())  # 202cb962ac59075b964b07152d234b70

就比如我们通过 MD5 算法加密一段字符串 "123" 得到的密文是 "202cb962ac59075b964b07152d234b70" , 我们是无法看懂或者是解密的, 那网上的 MD5 是怎么做到的, 其实他们就是将一些简单的密码 : 123,abc, 123456, abc123,..... 等等这种比较简单的低级密码都进行加密的一遍, 然后放在他们的数据库里边, 你在使用的时候恰巧就对比到一样的密文, 这就是 MD5 暴力破解

49 hashlib 与 hmac 模块

稍微加一个 @符号试试

import hashlib

m = hashlib.md5()
m.update("1234@".encode("utf-8"))
print(m.hexdigest())  # 2119eb59afc81b22cf8a4298047f9723

49 hashlib 与 hmac 模块

所以我们只要把密码设置复杂一点就不用怕 MD5 暴力破解了

ps : 2004 年 8 月 17 日的美国加州圣巴巴拉,正在召开的国际密码学会议, 来自山东大学的王小云教授做了破译 MD5、HAVAL-128、MD4 和 RIPEMD 算法的报告, 当时引发了密码学界的轩然大波, 但好像 MD5 算法团队又对 MD5 算法进行了修改, 到现在为止还是比较安全的

四. 模拟密文密码撞库

49 hashlib 与 hmac 模块

我们来模拟一下密码撞库

import hashlib,shelve

with shelve.open(r"./passed.txt")as f:
    while True:
        strs = input(" 输入明文进行密文入库(q 退出)>>").strip()
        if strs == "q":break
        m = hashlib.md5()
        m.update(strs.encode("utf-8"))
        res = m.hexdigest()
        f[strs] = res

with shelve.open(r"./passed.txt")as f1:
    while True:
        passwd_md5 = input(" 输入密文进行解密(q 退出)>>").strip()
        if passwd_md5 == "q": break
        for k,v in f1.items():
            if passwd_md5 == v:
                print(f" 明文密码 : {k}")
                break
        else:
            print(" 解密不成功, 我们会继续努力 ")

演示效果:

49 hashlib 与 hmac 模块

五. 模拟网上下载大文件进行 MD5 值计算的快速方式

假设一个 10G 的大文件, 要计算整个文件的 MD5 值会比较慢, 那么我们可以截取固定位置的字节来进行校验, 这样就快了很多, 甚至可以加盐对比, 这样一来就可以防止他们从中间恶意串改文件, 也可以加快速度

import os,hashlib,shutil

def auth(path):
    file_size = os.path.getsize(path)
    with open(path,"rb")as f:
        f.seek(0)                  # 指针在开头
        res1 = f.read(3)           # 取三个字节
        f.seek(file_size//10,0)    # 指针在十分之一处
        res2 = f.read(3)           # 取三个字节
        m = hashlib.md5()
        m.update(str(res1+res2).encode("utf-8"))
        return m.hexdigest()       # 六个字节加密后返回

hash1 = auth(r"D:\Python16 每日视频 \day05\ 视频 \08 文件处理.mp4")
print(hash1)  # bb0007474f0505b5ff24332733cf0ea5

# 拷贝文件模拟文件下载, 改变文件和路径
shutil.copyfile(r"D:\Python16 每日视频 \day05\ 视频 \08 文件处理.mp4","./aa.txt")

hash2 = auth("./aa.txt")
print(hash2)  # bb0007474f0505b5ff24332733cf0ea5

由上可知, 拷贝之后的文件与源文件得到的 MD5 摘要完全相同(这里我只演示了两处截取字节, 也没有加盐), 说明校验文件成功, 文件完整

ps : 我们下载一个文件的时候经常在 90% 或者 100% 的时候卡住一段时间, 其实这就是在进行 hash 值的校验, 如果校验不成功甚至会重新下载

49 hashlib 与 hmac 模块

正文完
 
shawn
版权声明:本站原创文章,由 shawn 2023-06-16发表,共计4849字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)