1、HMAC 概念

HMAC(Hash-based Message Authentication Code)基于 hash 的消息验证码,是 安全通信中必要的组成部件。

主要是 防止消息被篡改,和对称加密一起保护数据通信的 完整性。

参考HMAC实现规范,基于的 Hash 算法可以是 md5,sha1,sha-2(sha256,sha385,sha512)等;

在不考虑 hash算法具体实现的情况下,其实现原理图如下:

1)密钥填充

如果密钥比Hash函数的分组长度(block_size)要长,则要用Hash函数求出密钥的散列值,然后将这个散列值用作HMAC的密钥。

如果密钥比分组长度要短,就在末尾填充0,直到其长度达到单向散列函数的分组长度为止。

注:散列值长度digest_size 一般都会短于 分组长度block_size,因此,实际上 长于分组长度计算散列值之后,仍然需要在尾部填0。

2)填充后的密钥与ipad的XOR 将填充后的密钥,与被称为ipad的比特序列进行XOR运算。

ipad是将00110110这一比特序列(即16进制的36) 不断循环反复直到达到分组长度所形成的比特序列。其中:ipad的i 是inner的意思。

XOR运算所得到的值,就是一个和单向散列函数的分组长度相同,且和密钥相关的比特序列。这里我们将这个比特序列成为ipadkey。

3)与消息结合 将ipadkey与消息进行组合,也就是将和密钥相关的比特序列(ipadkey)附加在消息的开头

4)计算散列值 将步骤3的结果输入单向散列函数,并计算出散列值。

5)填充后的密钥与opad的XOR 将填充后的密钥与被称为opad的比特序列进行XOR运算。

opad是将01011100这一比特序列(即十六进制5C)不断循环反复直到达到分组长度所形成的比特序列,其中opad的o是outer的意思。

XOR运算所得到的结果也是一个和单向散列函数的分组长度相同,且和密钥相关的比特序列。这里我们将这个比特序列称为opadkey。

6)与散列值组合 opadkey附加在步骤4的散列值前面。

7)计算散列值 将步骤6的结果输入单向散列函数,并计算出散列值。这个值就是最终的MAC值。

2、HMAC Python hmac库实现

在 Python 中, 直接提供了 hmac 库实现相关操作。

如下所示,是yvivid基于 hmac库的一个实现。

更多hmac库的使用,请参考 python doc。

3、HMAC 的 笨办法( 仅利用Python hashlib库实现)

基于HMAC的原理,是否可以在已有 hash算法上,自己实现 HMAC算法。

下面是 yvivid 在 Python上,基于 hashlib库(hash算法)的基础上,HMAC自行编码的一个实现的。

1)由于 需要 XOR是实现,因此 使用了 int 和 bytes的转换,写的不是很简洁(逻辑电路的思维)。

2) i_key_pad 和 o_key_pad 实际上展开到 block_size长度了。

注:其实 在自己实现时,还没注意到 python的 hmac 库,结果是自己摸索 和 openssl输出进行对比分析的。

大家可自己分析 Python36\Lib\hmac.py 的代码。部分处理比我写的简洁,使用了 bytes的 ljust,translate特性。

但只有自己实现 才能感觉到其真实的原理。

4、易混淆的概念

1)填充阶段,尤其是 分组长度block_size 和 摘要(散列值)长度digest_size,

描述的概念比较混淆,导致编写代码过程走了弯路。

分组长度block_size 是 Hash 处理输入数据时,是按照 block_size大小来分块(block)处理的。

摘要(散列值)长度digest_size 是 Hash完成后,输出的 摘要(散列值)字节长度。

2)XOR 阶段,yvivid的实现采用了并行的思路,基于整数 的异或操作(python语法的 ^)。

3)Python 语法方面,对于 bytes 还是不熟悉,需要进一步学习。

附录:常用散列算法的分组长度和摘要长度。

单向散列函数 分组长度 block_size 摘要长度digest_size
MD5 64 Bytes (512bit) 16 Bytes (128bit)
SHA1 64 Bytes (512bit) 20 Bytes (160bit)
SHA256 64 Bytes (512bit) 32 Bytes (256bit)
SHA512 128 Bytes (1024bit)

64 Bytes (512bit)

原创声明:

HMAC原理是公共的,但 python代码实现(尤其是 基于hashlib下 自己的编写),是基于本人在 python 实现,转载请声明出处。

https://www.cnblogs.com/yvivid/p/hmac_basic.html

参考文献:

1) 图解密码技术(第3版) ,[日]结城浩;

学习笔记:http://flamepeak.com/2016/11/23/tu-jie-mi-ma-ji-shu-authentication20161123/

2) Python 3.6.8 documentation / Library Reference

hashlib — Secure hashes and message digests

hmac — Keyed-Hashing for Message Authentication

HMAC(Hash-based Message Authentication Code)实现原理的更多相关文章

  1. 消息认证码 - MAC (Message Authentication Code)

    消息认证包括两个目标 1消息完整性认证: 确保张三发给我的消息是完整的,在传输过程中没有被第三方篡改 2消息的来源认证: 确保这个数据是张三发给我的,而不是李四发给我的 第一个目标通常使用散列函数来达 ...

  2. Message Authentication Code

  3. MAC (Message Authentication Code,消息认证码算法)

    需要将密钥发送到对方,对方用该密钥进行摘要处理,进行摘要验证. //初始化KeyGenerator KeyGenerator keyGenerator= KeyGenerator.getInstanc ...

  4. 三种Hash算法对比以及秒传原理.

    三种Hash算法对比以及秒传原理 CRC (32/64)   MD5  Sha1 分5个点来说 1.校验值长度 2.校验值类别 3.安全级别 4.应用场景 1).校验值长度 CRC(32/64) 分别 ...

  5. Tencent://Message/协议的实现原理

    腾讯官方通过 Tencent://Message/协议可以让QQ用户显示QQ/TM的在线状态发布在互联网上:并且点击 XXX  ,不用加好友也可以聊天 官方链接: http://is.qq.com/w ...

  6. Tencent://Message/协议的实现原理(Windows提供协议注册)

    腾讯官方通过 Tencent://Message/协议可以让QQ用户显示QQ/TM的在线状态发布在互联网上:并且点击 XXX  ,不用加好友也可以聊天 官方链接: http://is.qq.com/w ...

  7. 密码学初级教程(五)消息认证码MAC-Message Authentication Code

    密码学家工具箱中的6个重要的工具: 对称密码 公钥密码 单向散列函数 消息认证码 数字签名 伪随机数生成器 MAC能识别出篡改和伪装,也就是既可以确认消息的完整性,也可以进行认证. 消息认证码的输入包 ...

  8. 汉明码(Hamming Code)原理及实现

    汉明码实现原理 汉明码(Hamming Code)是广泛用于内存和磁盘纠错的编码.汉明码不仅可以用来检测转移数据时发生的错误,还可以用来修正错误.(要注意的是,汉明码只能发现和修正一位错误,对于两位或 ...

  9. Codeforces Round #689 (Div. 2, based on Zed Code Competition) E. Water Level (贪心好题)

    题意:你在一家公司工作\(t\)天,负责给饮水机灌水,饮水机最初有\(k\)升水,水的范围必须要在\([l,r]\)内,同事每天白天都会喝\(x\)升水,你在每天大清早可以给饮水机灌\(y\)升水,问 ...

随机推荐

  1. PADS 9.5封装向导 多一个管脚

    使用PADS 9.5封装向导(Decal Wizard)建立封装(Decals) 时遇到封装的中间多了一个管脚,如图红圈位置,通过一番搜寻,才知道这是热焊盘,不需要就在右边的红圈处去掉勾选热焊盘即可.

  2. malloc/free函数

    一.malloc 函数原型:void *malloc(unsigned int size); 功       能:在内存的动态存储区中分配一个长度为size的连续空间. 返  回 值:指向所分配的连续 ...

  3. 火狐浏览器不支持location.reload()(以改变页面大小时重新刷新页面为例)

    背景:当页面大小改变时需要重新刷新页面,以适应相应的尺寸 解决方法: var url = window.location.href; var parm = parseInt(Math.random() ...

  4. UWP开发:应用设置存储

    应用设置储存指的是保存在应用程序储存区中的键/值对的字典集合,它自动负责序列化对象,并将其保存在应用程序里.以键/值对方式提供一种快速数据访问的方式,主要用于储存一些应用信息. 1,简介 应用设置是W ...

  5. python基础教程总结15——6 CGI远程编辑

    功能: 将文档作为普通网页显示: 在web表单的文本域内显示文档: 保存表单中的文本: 使用密码保护文档: 容易拓展,支持处理多余一个文档的情况 1.CGI CGI(Comment Gateway I ...

  6. UVA 10954 Add All 全部相加 (Huffman编码)

    题意:给你n个数的集合,每次选两个删除,把它们的和放回集合,直到集合的数只剩下一个,每次操作的开销是那两个数的和,求最小开销. Huffman编码.Huffman编码对于着一颗二叉树,这里的数对应着单 ...

  7. async/await的使用以及注意事项

    使用 async / await, 搭配 promise, 可以通过编写形似同步的代码来处理异步流程, 提高代码的简洁性和可读性. 本文介绍 async / await 的基本用法和一些注意事项. a ...

  8. c++链表-双向链表+增删查改

    基于双向链表的增删改查和排序(C++实现) 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前 ...

  9. python之函数名的应用

    1. 函数名是一个特殊的变量 例题 例题1: a = 1 b = 2 c = a + b print(c) # 输出结果 3 # 总结 # 变量是否可以进行相加或者拼接操作是又后面指向的值来决定的,指 ...

  10. Cordova 本地项目创建方法

    l  创建项目 需要在终端上输入:cordova create [目录][项目ID][APP名称] 运行:cordova create hello com.example.hello hello 将在 ...