hmac模块生成加入了密钥的消息摘要详解


Posted in Python onJanuary 11, 2018

hmac模块

hmac模块用于生成HMAC码。这个HMAC码可以用于验证消息的完整性,其原理也很简单,就是一种加入了密钥的消息摘要,相比起MAC更加安全。JWT(JSON Web Token)中第三部分的消息摘要就是使用了HMAC。

HMAC(Hash-based Message Authentication Code)

先大致介绍一下HMAC吧。HMAC是一种消息摘要算法,是一种特殊的MAC(消息认证码),内部使用别的摘要算法进行摘要的计算(比如MD5)。相比MAC,HMAC在生成摘要的时候加入了密钥,这使得HMAC码不仅可以用于验证消息完整性,并且保证了其无法被伪造。注意,摘要算法跟加密算法是有区别的。

整个算法可以总结为下图 图片来自wiki:

hmac模块生成加入了密钥的消息摘要详解

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查阅,或者查看知乎上的问答如何通俗地解释时序攻击。

总结

以上就是本文关于hmac模块生成加入了密钥的消息摘要详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

Python 相关文章推荐
python数据结构之二叉树的统计与转换实例
Apr 29 Python
在IIS服务器上以CGI方式运行Python脚本的教程
Apr 25 Python
python发送邮件功能实现代码
Jul 15 Python
python先序遍历二叉树问题
Nov 10 Python
python使用rpc框架gRPC的方法
Aug 24 Python
python 用opencv调用训练好的模型进行识别的方法
Dec 07 Python
Python+threading模块对单个接口进行并发测试
Jun 25 Python
浅谈python3中input输入的使用
Aug 02 Python
python中seaborn包常用图形使用详解
Nov 25 Python
pytorch中的inference使用实例
Feb 20 Python
基于K.image_data_format() == 'channels_first' 的理解
Jun 29 Python
Pycharm打开已有项目配置python环境的方法
Jul 03 Python
快速了解Python中的装饰器
Jan 11 #Python
简单了解python模块概念
Jan 11 #Python
100行Python代码实现自动抢火车票(附源码)
Jan 11 #Python
python实现外卖信息管理系统
Jan 11 #Python
Python实现学生成绩管理系统
Apr 05 #Python
名片管理系统python版
Jan 11 #Python
Python学生成绩管理系统简洁版
Apr 05 #Python
You might like
php开启openssl的方法
2014/05/15 PHP
php使用fopen创建utf8编码文件的方法
2014/10/31 PHP
PHP实现将科学计数法转换为原始数字字符串的方法
2014/12/16 PHP
PHP在线打包下载功能示例
2016/10/15 PHP
js的.innerHTML = ""IE9下显示有错误的解决方法
2013/09/16 Javascript
JS+CSS 制作的超级简单的下拉菜单附图
2013/11/22 Javascript
nodejs实现黑名单中间件设计
2014/06/17 NodeJs
详解JavaScript基于面向对象之继承
2015/12/13 Javascript
easyui window refresh 刷新两次的解决方法(推荐)
2016/05/18 Javascript
VUE使用vuex解决模块间传值问题的方法
2017/06/01 Javascript
JS实现经典的中国地区三级联动下拉菜单功能实例【测试可用】
2017/06/06 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
2017/07/17 Javascript
js阻止默认右键的下拉菜单方法
2018/01/02 Javascript
vue嵌套路由与404重定向实现方法分析
2018/05/04 Javascript
react实现点击选中的li高亮的示例代码
2018/05/24 Javascript
JS简易计算器实例讲解
2020/06/30 Javascript
[01:02]DOTA2辉夜杯决赛日 CDEC.Y对阵VG赛前花絮
2015/12/27 DOTA
[02:42]完美大师赛主赛事淘汰赛第三日观众采访
2017/11/25 DOTA
Python实现简单的可逆加密程序实例
2015/03/05 Python
浅谈Python中的闭包
2015/07/08 Python
nohup后台启动Python脚本,log不刷新的解决方法
2019/01/14 Python
pd.DataFrame统计各列数值多少的实例
2019/12/05 Python
Python3读写Excel文件(使用xlrd,xlsxwriter,openpyxl3种方式读写实例与优劣)
2020/02/13 Python
Pytorch 使用CNN图像分类的实现
2020/06/16 Python
Python在字符串中处理html和xml的方法
2020/07/31 Python
如何基于matlab相机标定导出xml文件
2020/11/02 Python
日本小田急百货官网:Odakyu
2018/07/19 全球购物
C# Debug和Testing相关面试题
2015/10/25 面试题
酒店管理求职信范文
2014/04/06 职场文书
师德师风演讲稿
2014/05/05 职场文书
首都博物馆观后感
2015/06/05 职场文书
如何让2019年上半年的工作总结更出色!
2019/07/01 职场文书
导游词之蓬莱长岛
2019/12/17 职场文书
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
2021/05/21 Redis
Go Plugins插件的实现方式
2021/08/07 Golang
mysql查看表结构的三种方法总结
2022/07/07 MySQL