Python 哈希加密的魔法盒子 ——hashlib模块全解析

Python 哈希加密的魔法盒子 ——hashlib模块全解析

在 Python 编程世界里,hashlib模块就像一个神奇的魔法盒子,为开发者提供了众多安全哈希和消息摘要算法的实现接口。无论是数据完整性验证、密码加密存储,还是数字签名等领域,它都发挥着关键作用。本文将深入剖析hashlib模块,带你从基础概念到高级应用,逐步掌握其精髓,让你在数据安全处理方面游刃有余。

一、hashlib模块概述

hashlib模块是 Python 标准库的一部分,主要用于实现多种安全哈希和消息摘要算法。它提供了一个通用接口,涵盖了如 FIPS 安全哈希算法(SHA 系列)、RSA 的 MD5 算法等。在数据处理过程中,这些算法能将任意长度的数据转换为固定长度的哈希值,就像为数据生成了独一无二的 “指纹”,方便进行数据的快速比较、验证和加密处理。

二、哈希算法类型及构造器

(一)常见哈希算法构造器

  1. 始终可用的构造器sha1()sha224()sha256()sha384()sha512()sha3_224()sha3_256()sha3_384()sha3_512()shake_128()shake_256()blake2b()blake2s() 等构造器在所有平台上都保证可用。例如,使用sha256()构造器创建一个 SHA - 256 哈希对象:
import hashlib
m = hashlib.sha256()
  1. md5()构造器md5()通常也是可用的,但在 “FIPS 兼容” 的 Python 编译版中可能缺失或被屏蔽。这是因为 MD5 算法存在已知的碰撞弱点,安全性相对较低,不建议在安全要求高的场景中使用。

(二)通用构造器new()

hashlib.new(name, [data, ], *, usedforsecurity=True)是一个通用构造器,通过传入算法名称字符串name,可以创建对应算法的哈希对象。它不仅能访问常见算法,还能使用 OpenSSL 库提供的其他算法。比如创建 SHA - 256 哈希对象:

h = hashlib.new('sha256')

相较于直接使用sha256()构造器,new()的灵活性更高,在处理一些不确定算法名称的动态场景时非常实用。

(三)构造器参数usedforsecurity

从 Python 3.9 版本开始,所有hashlib的构造器都接受usedforsecurity这个仅限关键字参数,默认值为True。当设置为False时,允许在受限环境中使用不安全且阻塞的哈希算法,比如将其用作非加密的单向压缩函数。但在实际开发中,为确保数据安全,在安全相关场景下应保持默认值或谨慎使用该参数。

三、hashlib模块的属性

(一)algorithms_guaranteed

这是一个集合,包含了hashlib模块在所有平台上都保证支持的哈希算法名称。即使某些 “FIPS 兼容” 编译版可能会排除md5,但它依然在这个集合中。通过访问该属性,可以快速获取通用支持的算法列表:

import hashlib
print(hashlib.algorithms_guaranteed)

(二)algorithms_available

该集合包含了在当前运行的 Python 解释器上可用的所有哈希算法名称。它是algorithms_guaranteed的超集,其中的算法名称可作为new()函数的参数。由于 OpenSSL 的原因,同一算法可能以不同名称多次出现。在开发中,如果需要动态获取当前环境支持的所有算法,可使用该属性:

import hashlib
print(hashlib.algorithms_available)

四、哈希对象的属性和方法

(一)属性

  1. digest_size:表示结果哈希对象的大小(以字节为单位)。例如,sha256哈希对象的digest_size为 32 字节:
import hashlib
m = hashlib.sha256()
print(m.digest_size)  
  1. block_size:代表哈希算法的内部块大小(以字节为单位),不同算法的block_size不同,它在算法的内部计算过程中起着重要作用。
  2. name:此哈希对象的规范名称,始终为小写形式,可作为new()的参数创建相同类型的哈希对象。在 Python 3.4 之前,该属性虽存在于 CPython 中,但未正式指明,可能在某些平台不可用。

(二)方法

  1. update(data):用于使用字节类对象(通常是bytes)来更新哈希对象。多次调用update方法的效果等同于一次性传入所有数据的拼接结果。例如:
import hashlib
m = hashlib.sha256()
m.update(b"Nobody inspects")
m.update(b" the spammish repetition")
  1. digest():返回当前已传给update()方法的数据摘要,是一个大小为digest_size的字节串对象,字节值范围为 0 - 255。
  2. hexdigest():与digest()类似,但摘要以两倍长度的字符串对象形式返回,仅包含十六进制数码。这种格式便于在电子邮件或其他非二进制环境中安全交换数据值。例如:
import hashlib
m = hashlib.sha256(b"Nobody inspects the spammish repetition")
print(m.hexdigest())
  1. copy():返回哈希对象的副本(“克隆”),可用于高效计算共享相同初始子串的数据的摘要。比如在处理大量相似数据时,先创建一个哈希对象并更新部分公共数据,然后通过copy()方法复制对象,再分别更新不同部分的数据,可减少重复计算。

五、SHAKE 可变长度摘要

(一)构造器

hashlib.shake_128([data, ], *, usedforsecurity=True)hashlib.shake_256([data, ], *, usedforsecurity=True)算法提供可变长度摘要。shake_128可生成长度在length_in_bits//2至 128 位之间的摘要,shake_256可生成长度在length_in_bits//2至 256 位之间的摘要,且不限制最大长度。

(二)方法

  1. digest(length):返回当前已传给update()方法的数据摘要,是一个大小为length的字节串对象。
  2. hexdigest(length):与digest(length)类似,但摘要以两倍长度的十六进制字符串形式返回。例如:
import hashlib
h = hashlib.shake_256(b'Nobody inspects the spammish repetition')
print(h.hexdigest(20))

六、文件哈希

hashlib.file_digest(fileobj, digest, /)函数用于对文件或文件型对象进行高效哈希操作。其中,fileobj必须是以二进制模式打开用于读取的文件型对象,digest可以是哈希算法名称、哈希构造器或返回哈希对象的可调用对象。该函数返回根据文件内容更新的摘要对象,在文件完整性校验等场景中应用广泛。例如:

import io, hashlib
with open(hashlib.__file__, "rb") as f:
    digest = hashlib.file_digest(f, "sha256")
print(digest.hexdigest())

七、密钥派生

(一)pbkdf2_hmac函数

hashlib.pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None)提供 PKCS#5 基于密码的密钥派生函数 2。它使用 HMAC 作为伪随机函数,其中hash_name指定哈希摘要算法,passwordsalt需为字节串,iterations根据哈希算法和机器算力选择,dklen为派生密钥长度。在 2022 年,建议对 SHA - 256 进行数万次迭代。例如:

from hashlib import pbkdf2_hmac
our_app_iters = 500_000
dk = pbkdf2_hmac('sha256', b'password', b'bad salt'*2, our_app_iters)
print(dk.hex())

该函数只有在 Python 附带 OpenSSL 编译时才可用,从 Python 3.12 版本开始,慢速的纯 Python 实现已被移除。

(二)scrypt函数

hashlib.scrypt(password, *, salt, n, r, p, maxmem=0, dklen=64)提供基于密码加密的密钥派生函数,定义在 RFC 7914 中。passwordsalt为字节类对象,n是 CPU / 内存开销因子,r是块大小,p是并行化因子,maxmem是内存上限(OpenSSL 1.1.0 默认为 32 MiB),dklen是派生密钥长度。

函数适用场景参数特点安全性性能
pbkdf2_hmac适用于一般的密钥派生场景,对兼容性要求较高参数相对简单,主要关注哈希算法、密码、盐值、迭代次数和密钥长度安全性取决于所选哈希算法和迭代次数,迭代次数足够时安全性较高性能相对稳定,迭代次数增加会导致计算时间增长
scrypt对内存和 CPU 资源管理要求较高,需要更复杂的密钥派生策略的场景参数复杂,涉及 CPU / 内存开销因子、块大小、并行化因子等多个影响性能和安全性的参数通过复杂参数设置提供较高安全性,对暴力攻击有较好的防御能力计算过程对内存和 CPU 资源消耗较大,但安全性更高

八、BLAKE2

(一)BLAKE2 概述

BLAKE2 是在 RFC 7693 中定义的加密哈希函数,有 BLAKE2b 和 BLAKE2s 两种形式。BLAKE2b 针对 64 位平台优化,可生成长度介于 1 - 64 字节的摘要;BLAKE2s 针对 8 - 32 位平台优化,可生成长度介于 1 - 32 字节的摘要。它支持多种特性,如密钥模式、加盐哈希、个性化和树形哈希。

(二)创建哈希对象

通过调用构造器函数hashlib.blake2b(data=b'', *, digest_size=64, key=b'', salt=b'', person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False, usedforsecurity=True)hashlib.blake2s(data=b'', *, digest_size=32, key=b'', salt=b'', person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False, usedforsecurity=True)创建哈希对象。这些构造器接受多种参数,用于定制哈希计算过程。

(三)BLAKE2 的应用场景

  1. 简单哈希:与其他哈希算法类似,通过构造哈希对象、更新数据、获取摘要的步骤计算数据哈希值。
  2. 使用不同的摘要大小:BLAKE2 的摘要大小可配置,不同摘要大小的哈希对象输出不同,即使长度相同,BLAKE2b 和 BLAKE2s 的输出也不同,可根据需求选择合适的摘要长度。
  3. 密钥哈希:可用于身份验证,作为 HMAC 的替代方案,比 HMAC 更快速简单。例如在 Web 应用中为 cookies 签名验证,防止数据篡改。
  4. 随机哈希:通过设置salt参数引入随机化,防止数字签名中的碰撞攻击,但不适用于密码哈希。
  5. 个性化:通过person参数传入字节串,使哈希函数为相同输入生成不同摘要,可用于防止协议中哈希值被滥用,也可用于派生多个不同密钥。
  6. 树形模式:适用于处理复杂数据结构的哈希计算,如文件系统目录树的哈希校验等场景,通过设置树形哈希参数实现高效准确的哈希计算。

总结

hashlib模块作为 Python 在安全哈希和消息摘要领域的重要工具,提供了丰富多样的算法和功能。从基本的哈希计算到复杂的密钥派生,从文件哈希处理到具有多种特性的 BLAKE2 算法应用,它在数据安全、完整性验证、密码管理等众多场景中都不可或缺。在使用过程中,需要根据具体需求选择合适的算法和参数,同时要注意算法的安全性和性能问题。随着技术的发展,哈希算法的安全性要求也在不断提高,开发者应持续关注相关领域的动态,确保应用程序的数据安全。

TAG:Python;hashlib模块;哈希算法;消息摘要;密钥派生;数据安全

相关学习资源

  1. Python 官方文档 - hashlib模块 https://docs.python.org/zh-cn/3.12/library/hashlib.html Python 官方提供的hashlib模块详细文档,包含模块概述、函数和类的用法、示例代码等,是学习hashlib最权威的资料。
  2. 《Python 密码学编程》 深入讲解 Python 在密码学领域的应用,其中包含大量关于hashlib模块的实际案例和原理剖析,帮助读者理解哈希算法在密码学中的作用和应用场景。
  3. Tekin的Python编程秘籍库Python 实用知识与技巧分享,涵盖基础、爬虫、数据分析等干货 本 Python 专栏聚焦实用知识,深入剖析基础语法、数据结构。分享爬虫、数据分析等热门领域实战技巧,辅以代码示例。无论新手入门还是进阶提升,都能在此收获满满干货,快速掌握 Python 编程精髓。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tekin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值