密码学系列之:Merkle–Damgård结构和长度延展攻击
密码学系列之:Merkle–Damgård结构和长度延展攻击
简介
Merkle–Damgård结构简称为MD结构,主要用在hash算法中抵御碰撞攻击。这个结构是一些优秀的hash算法,比如MD5,SHA-1和SHA-2的基础。今天给大家讲解一下这个MD结构和对他进行的长度延展攻击。
MD结构
MD结构是Ralph Merkle在1979年的博士论文中描述的。因为Ralph Merkle 和 Ivan Damgård 分别证明了这个结构的合理性,所以这个结构被称为Merkle–Damgård结构。
接下来,我们看下MD结构是怎么工作的。
MD结构首先对输入消息进行填充,让消息变成固定长度的整数倍(比如512或者1024)。这是因为压缩算法是不能对任意长度的消息进行处理的,所以在处理之前必须进行填充。
通常来说,我们会使用恒定的数据,比如说0来填充整个消息块。
举个例子,假如我们的消息是“HashInput”,压缩块的大小是8字节(64位),那么我们的消息将会被分成两个块,后面一个块使用0来填充,将会得到:“HashInpu t0000000”。
但是这样做往往是不够的,因为通常对于压缩函数来说,会删除掉最后面的额外的0,所以导致填充和不填充最后计算出来的hash值是一样的。
为避免这种情况,必须更改填充常量数据的第一位。由于常量填充通常由零组成,因此第一个填充位将强制更改为“ 1”。
也就是“HashInpu t1000000”。
我们还可以对填充进行进一步的增强,比如使用一个额外的block来填充消息的长度。
但是额外的使用一个block往往有点浪费,一个更加节约空间的做法就是,如果填充到最后一个block的0中有住够的空间的话,那么可以消息的长度放在那里。
填充好block之后,接下来就可以对消息进行压缩了,我们看下一下MD的流程图:

消息被分成了很多个block,最开始的初始化向量和第一个block进行f操作,得到了的结果再和第二个block进行操作,如此循环进行,最终得到了最后的结果。
长度延展攻击
在密码学中长度延展攻击就是指攻击者通过已知的hash(message1)和message1的长度,从而能够知道hash(message1‖message2)的值。其中‖ 表示的是连接符。并且攻击性并需要知道message1到底是什么。
上一节我们讲到的MD结构,是将消息分成一个一个的block,前一个block 运算出来的值会跟下一个block再次进行运算,这种结构可以很方便的进行长度延展攻击。前提是我们需要知道原消息的长度。
我们举个例子,假设我们有下面的请求:
Original Data: count=10&lat=37.351&user_id=1&long=-119.827&waffle=eggo
Original Signature: 6d5f807e23db210bc254a28be2d6759a0f5f5d99
上面的例子是给编号为1的用户发送鸡蛋馅的华夫饼,并附带了消息签名,以保证消息的正确性。这里消息签名使用的MAC算法。
假如恶意攻击者想把waffle的值从eggo修改成为liege。
那么新的数据将会是这样的:
count=10&lat=37.351&user_id=1&long=-119.827&waffle=eggo&waffle=liege
为了对该新消息进行签名,通常,攻击者需要知道该消息签名使用的密钥,并通过生成新的MAC来生成新的签名。但是,通过长度扩展攻击,可以将哈希(上面给出的签名)作为输入,并在原始请求已中断的地方继续进行hash输出,只要知道原始请求的长度即可。
如果考虑到padding(消息填充)的影响的话,我们还需要恢复原始消息的填充内容,然后在恢复过后的内容之后再添加我们的攻击代码:
New Data: count=10&lat=37.351&user_id=1&long=-119.827&waffle=eggo\x80\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x02\x28&waffle=liege
这样我们就可以得到新的MAC值:
New Signature: 0e41270260895979317fff3898ab85668953aaa2
Wide pipe
为了避免长度延展攻击,我们可以对MD结构进行一些变形。
先看一下Wide Pipe结构:

wide pipe和MD的流程基本上是一致的,不同的是生成的中间临时的加密后的消息长度是最终生成消息长度的两倍。
这也就是为什么上图中会有两个初始向量IV1 和 IV2。假如最终的结果长度是n的话,那么在中间生成的结果的长度就是2n。我们需要在最后的final 这一步中,将2n长度的数据缩减为n长度的数据。
SHA-512/224 和 SHA-512/256 只是简单的丢弃掉一半数据。
Fast wide pipe
还有一种比wide pipe更快的算法叫做fast wide pipe:

和wide pipe不同的是,它的主要思想是将前一个链接值的一半转发给XOR,然后将其与压缩函数的输出进行XOR。
本文已收录于 http://www.flydean.com/md-length-extension/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
密码学系列之:Merkle–Damgård结构和长度延展攻击的更多相关文章
- 浅谈HASH长度拓展攻击
前言 最近在做CTF题的时候遇到这个考点,想起来自己之前在做实验吧的入门CTF题的时候遇到过这个点,当时觉得难如看天书一般,现在回头望去,仔细琢磨一番感觉也不是那么难,这里就写篇文章记录一下自己的学习 ...
- 密码学系列之:feistel cipher
密码学系列之:feistel cipher 简介 feistel cipher也叫做Luby–Rackoff分组密码,是用来构建分组加密算法的对称结构.它是由德籍密码学家Horst Feistel在I ...
- 密码学系列之:memory-hard函数
密码学系列之:memory-hard函数 目录 简介 为什么需要MHF Memory hard的评估方法 MHF的种类 MHF的密码学意义 memory-hard在MHF中的应用 简介 Memory ...
- 密码学系列之:碰撞抵御和碰撞攻击collision attack
密码学系列之:碰撞抵御和碰撞攻击collision attack 简介 hash是密码学和平时的程序中经常会用到的一个功能,如果hash算法设计的不好,会产生hash碰撞,甚至产生碰撞攻击. 今天和大 ...
- 【Xamarin开发 Android 系列 7】 Android 结构基础(下)
原文:[Xamarin开发 Android 系列 7] Android 结构基础(下) *******前期我们不打算进行太深入的东西,省的吓跑刚进门的,感觉门槛高,so,我们一开始就是跑马灯一样,向前 ...
- 【Xamarin开发 Android 系列 6】 Android 结构基础(上)
原文:[Xamarin开发 Android 系列 6] Android 结构基础(上) 前面大家已经熟悉了什么是Android,而且在 [Xamarin开发 Android 系列 4] Android ...
- 密码学系列之:memory-bound函数
密码学系列之:memory-bound函数 目录 简介 内存函数 内存受限函数 内存受限函数的使用 简介 memory-bound函数可以称为内存受限函数,它是指完成给定计算问题的时间主要取决于保存工 ...
- vue 快速入门 系列 —— Vue(自身) 项目结构
其他章节请看: vue 快速入门 系列 Vue(自身) 项目结构 前面我们已经陆续研究了 vue 的核心原理:数据侦测.模板和虚拟 DOM,都是偏底层的.本篇将和大家一起来看一下 vue 自身这个项目 ...
- 哈希长度扩展攻击的简介以及HashPump安装使用方法
哈希长度扩展攻击(hash length extension attacks)是指针对某些允许包含额外信息的加密散列函数的攻击手段.该攻击适用于在消息与密钥的长度已知的情形下,所有采取了 H(密钥 ∥ ...
随机推荐
- Megengine量化
Megengine量化 量化指的是将浮点数模型(一般是32位浮点数)的权重或激活值用位数更少的数值类型(比如8位整数.16位浮点数)来近似表示的过程. 量化后的模型会占用更小的存储空间,还能够利用许多 ...
- NVIDIA空中导航SDK改造5G通信
NVIDIA空中导航SDK改造5G通信 Transforming Next-Generation Wireless with 5T for 5G and the NVIDIA Aerial SDK N ...
- 【NX二次开发】UF_OBJ_ask_display_properties获取对象所在层、获取对象颜色、获取对象是否隐藏、获取对象是否高亮,获取对象线宽、字体大小
UF_OBJ_ask_display_properties 返回一个对象的显示属性(层.颜色.隐藏状态.线宽和字体). UF_OBJ_disp_props_p_t结构体: layer int 对象所在 ...
- 【NX二次开发】判断部件是否已修改(判断部件是否需要保存)UF_PART_is_modified();
判断部件是否已修改(判断部件是否需要保存)UF_PART_is_modified(); 注意:函数需要输入原型,不要输入事例.事例转原型:UF_ASSEM_ask_prototype_of_occ() ...
- 04-拉格朗日对偶问题和KKT条件
04-拉格朗日对偶问题和KKT条件 目录 一.拉格朗日对偶函数 二.拉格朗日对偶问题 三.强弱对偶的几何解释 四.鞍点解释 4.1 鞍点的基础定义 4.2 极大极小不等式和鞍点性质 五.最优性条件与 ...
- LTDC_DMA2D驱动实验
STM32F429芯片使用LTDC.DMA2D.及RAM存储器,构成了一个完整的液晶控制器.LTDC负责不断刷新液晶屏(将数据从显存搬运到液晶屏),DMA2D用于图像数据搬运.混合及格式转换(将数据搬 ...
- React-Antd4的Form表单校验
之前很少用react做项目,最近入职新公司,用的react,在自己的摸索过程中,慢慢会记录一些使用方法.今天简单记录一下使用antd 4.0版本的Form表单校验,直接代码. 需要购买阿里云产品和服务 ...
- 关于kubernetes的十七个实验(二)
写在开头 时隔好几天,结束了毕业设计中期答辩,更新第二节. 实验二与Kubeadm Kubeadm解决了以下问题:处理TLS加密配置,部署核心Kubernetes组件并确保其他节点可以轻松加入集群. ...
- 简单聊聊Ehcache缓存
最近工作没有那么忙,有时间来写写东西.今年的系统分析师报名已经开始了,面对历年的真题,真的难以入笔,所以突然对未来充满了担忧,还是得抓紧时间学习技术. 同事推了一篇软文,看到了这个Ehcache,感觉 ...
- js关于数组的操作(合并数组、添加数组、循环等)
1. concat() 方法 concat() 方法用于连接两个或多个数组 var arr = new Array(3) arr[0] = "George" arr[1] = &q ...