hmac模块生成加入了密钥的消息摘要详解
作者:GanZiQim 时间:2023-05-17 09:26:46
hmac模块
hmac模块用于生成HMAC码。这个HMAC码可以用于验证消息的完整性,其原理也很简单,就是一种加入了密钥的消息摘要,相比起MAC更加安全。JWT(JSON Web Token)中第三部分的消息摘要就是使用了HMAC。
HMAC(Hash-based Message Authentication Code)
先大致介绍一下HMAC吧。HMAC是一种消息摘要算法,是一种特殊的MAC(消息认证码),内部使用别的摘要算法进行摘要的计算(比如MD5)。相比MAC,HMAC在生成摘要的时候加入了密钥,这使得HMAC码不仅可以用于验证消息完整性,并且保证了其无法被伪造。注意,摘要算法跟加密算法是有区别的。
整个算法可以总结为下图 图片来自wiki:
K:key,密钥
K':调整长度之后的密钥
m:message,消息
H:hash function,消息摘要算法
opad:outer padding,一个块长度的十六进制常数,Ox5c5c5c…5c
ipad:inner padding,一个块长度的十六进制常数,Ox363636…36
计算步骤:
如果K的长度大于使用的摘要算法的Block Size(比如MD5中是64),HMAC算法会先计算K的摘要,而当K的长度小于Block Size时则用0进行填充。这一步得到结果K'。
将K'与ipad做异或运算。
上一步的结果加上m并计算消息摘要值。
将K'与opad做异或运算。
上一步的结果加上第三步的结果并计算消息摘要值,这一步的结果为最终结果。
hmac.HMAC(key, msg=None, digestmod=None)
hmac模块中最核心的就是HMAC类,可以直接通过实例化来获取该类的实例,也可以通过调用函数hmac.new(key, msg=None, digestmod=None)获取。
参数key可以是一个bytes对象或者bytearray对象,是用于加密的密钥。如果key大于Block Size(默认是64),会先计算一次消息摘要,小于的话用0填充到与Block Size相同的长度。
参数msg是用于加密的消息。
参数digestmod是用于计算摘要的算法,默认使用hashlib.md5。这个参数支持三种类型的值:
可以是hashlib里面的其他的构造器,比如hashlib.sha1、hashlib.sha256等
可以是一个字符串,会调用hashlib.new(digestmod)获取相应的构造器
可以是一个符合PEP247标准的模块,这时会调用digestmod.new()
API
HMAC.update(msg)
更新HMAC对象的内容,附加到之前的msg后面。
HMAC.digest()
返回消息摘要值。因为HMAC.update()会动态修改msg内容,所以每次都会重新计算。
HMAC.hexdigest()
以十六进制的形式返回消息摘要值。因为HMAC.update()会动态修改msg内容,所以每次都会重新计算。
HMAC.copy()
返回HMAC对象的克隆,用于在两个对象内容拥有相同部分的时候提高效率,修改克隆的对象不会影响原对象。
有一个地方很有意思,这个函数在内部是调用self.__class__.__new__(self.__class__),再把关键参数赋值给新对象,这样做会比直接调用__init__的效率高一些。
属性
HMAC.digest_size
摘要值的长度。
HMAC.block_size
如果根据参数digestmod获取的构造器没有Block Size或者小于16,会使用默认值64。
HMAC.name
HMAC的名字,值为hmac-{内部摘要算法名字},比如hamc-md5。
hmac.compare_digest(a, b)
在hmac模块中,通过from _operator import _compare_digest as compare_digest引入了这个函数。这个函数简单点来说就是用来比较a与b值是否相等的,当将外部输入的值与HMAC.degest()/HMAC.hexdigest()的输出做比较时,有可能会遭到时序攻击,所以可以通过调用这个函数比较值并防御可能存在的攻击行为。Python3.3版本后新增。
至于什么是“时序攻击”,大家可以自行上wiki查阅,或者查看知乎上的问答如何通俗地解释时序攻击。
来源:http://blog.csdn.net/jy692405180/article/details/78636767