Python hashlib与hmac模块详解:从基础摘要到HMAC签名实战
本文详细解析Python中hashlib和hmac模块的使用方法。介绍hashlib生成MD5、SHA1等摘要算法的原理及二进制数据处理方式,并通过示例演示update函数的分块应用。重点讲解hmac模块如何通过密钥干扰提升安全性,对比直接拼接与HMAC算法的差异,最后梳理各哈希算法的输出长度与位数对应关系,为API签名及数据完整性校验提供实用参考。
本文深入解析Python中hashlib和hmac模块的具体用法,通过详细示例代码展示其操作细节,旨在为开发者在学习或实际工作中提供有价值的参考。
在编写自动化脚本时,遇到了一个包含加密信号标签的文件无法正常运行。
import hashlib
import time
m = hashlib.md5()
api_key = ''
api_secret = ''
params = {'api_key':api_key, 'time':int(time.time()), 'symbol':'btclcny'}
def sign( data , secret ):
signStr = ""
keys = data.keys()
keys = sorted(keys)
for key in keys:
signStr = signStr + key
signStr = signStr + bytes(data[key])
pass
signStr += secret
m.update(signStr)
return m.hexdigest()
print sign( params , api_secret )
由于不清楚原作者的设计意图,代码中出现了字符串与字节码直接相加的情况,导致程序无法执行。鉴于本人对加密模块使用经验较少,此次问题恰好成为记录和学习的机会。
该平台接口存在明显问题,耗费了大量排查时间。后续查阅其PHP源码时感到困惑,经过对传入参数的仔细研究,发现接口文档描述混乱,进一步浪费了时间。
hashlib模块基础与摘要算法原理
接下来进入主题,首先讲解hashlib模块,随后介绍hmac模块。若有时间,后续章节还将涵盖base64、io、pickle、json、shelve以及fileinput等模块的使用。
概念解析:
Python的hashlib库提供了多种常见的摘要算法支持,例如MD5和SHA1等。
摘要算法,也被称为哈希算法或散列算法,其核心功能是通过特定函数将任意长度的数据转换为固定长度的数据串,通常以16进制字符串形式呈现。因此,经过hash加密后的值仅包含0-9和a-f字符。
后续可通过测试不同加密算法的输出字段长度,来确定具体输出的字节数(注意:一个16进制字符对应4位二进制,即半个字节)。
'''初始化对象'''
h1 = hashlib.md5()
h2 = hashlib.new('md5')
h3 = hashlib.md5()
h1.update(b'123') # 进行摘要
h2.update('123'.encode())
h3.update(b'1')
h3.update(b'23')
print(h1.hexdigest()) # 取值
print(h2.hexdigest())
print(h3.hexdigest())
202cb962ac59075b964b07152d234b70<br data-filtered="filtered">202cb962ac59075b964b07152d234b70<br data-filtered="filtered">202cb962ac59075b964b07152d234b70
hashlib实例化与update方法使用
实例化hash对象主要有两种方式,通常教程中介绍的是第一种。需特别注意,进行MD5摘要处理时,输入数据必须为二进制格式。
update方法可以多次调用,只要处理的数据内容未变,分段调用在处理大文件时通常比一次性处理更高效,这也是书籍中推荐的做法。
hmac模块与干扰加密实战
若直接进行加密而不添加辅助字符,当用户密码设置过于简单时,攻击者可能通过逆向分析加密后的数据推测出原始密码,因此需要引入干扰词汇以增强安全性。
hmac模块提供了一种相对更高级的干扰加密写法,用于提升数据安全性。
add_word = b'haha' # 把这个当做加密盐,
hh1 = hashlib.md5()
hh1.update(add_word + b'jiujiu')
print(hh1.hexdigest())
hh2 = hashlib.md5()
hh2.update( b'jiujiu' + add_word)
print(hh2.hexdigest())
m = hmac.new(add_word) # 这个跟hashlib的写法有点类似,默认是md5加密
m.update(b'jiujiu')
print(m.hexdigest())
h_md5 = hmac.new(add_word, b'jiujiu').hexdigest() # 这是另外一种方式,直接加密后取值。
h_sha1 = hmac.new(add_word, b'jiujiu', 'sha1').hexdigest()
h_sha224 = hmac.new(add_word, b'jiujiu', 'sha224').hexdigest()
h_sha256 = hmac.new(add_word, b'jiujiu', 'sha256').hexdigest()
h_sha512 = hmac.new(add_word, b'jiujiu', 'sha512').hexdigest()
print(h_md5, len(h_md5), sep='======>num')
print(h_sha1, len(h_sha1), sep='======>num') # 通过输出可以看出,md5输出32个16进制数字,一共128位
print(h_sha224, len(h_sha224), sep='======>num') # sha1输出40个数字,所以为160位,剩下的sha后面的数字就代表输出几位。
print(h_sha256, len(h_sha256), sep='======>num')
print(h_sha512, len(h_sha512), sep='======>num')
3e289c523f955430bce2e47a14d4934b
eb01e09a1fe2bfd95d8f31c8ae544faf
ef84bc9ee2bf91d1789227d82193d7a9
ef84bc9ee2bf91d1789227d82193d7a9======>num32
fbd95ddafdac6352cdf3d9d4e8c6d2421c80e56c======>num40
60d1896d00e73bc67469a58b39ded91c60c162eda0f44306f7d08d58======>num56
b36f8977bba6265612bc338b89c698d17cff7ccfb81b7d7a434f0ad889995e26======>num64
043f51bd410f9d328ca0ab0913ddfde9c2519f639c74447a1516811b8920b125aa6f4d3977c83e038e82c39103ac2a3bbdd5235c9c95fc030a267cdf0d578696======>num128
从代码操作层面看,实现过程相对简单,至少比预想中容易。虽然我不完全理解其背后的加密逻辑,且深知密码学涉及高深的数学知识,但这部分留待日后有空时再深入研究。
hmac本质上是一种机器加密手段。经测试发现,无论将加密盐(key)放置在加密字节码的前面还是后面,最终生成的HMAC结果均不相同,这表明其内部拥有特定的拼接加密算法,而非简单的字符串连接。
常见哈希算法输出长度对比
对于sha1、sha256和sha512等算法,其命名规则较为直观:md5输出32个16进制数,对应128位(bit);sha1输出40个16进制数,对应160位(bit);其余算法同理,数字后缀代表了输出的位数大小。
以上就是本文的全部内容,希望能为读者带来帮助,也欢迎大家继续支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













