首页 > 解决方案 > 具有起始值的 Python hashlib SHA256

问题描述

我想为大学任务处理 HMAC* 长度扩展攻击。因此,我同时提供了一个 HMAC* 和相应的消息,并且想要附加另一个任意消息并在没有密钥的情况下重新计算 HMAC。关于我们的讲座,这是可能的并且是非常常见的攻击场景。

我的问题是基于实现的:为了推动这种攻击,我需要用我已经拥有的现有 HMAC* 替换默认的 SHA256 起始值(h0 到 h7)。因为我没有钥匙,所以只推入原始数据是不可能的。

除了重新实现 SHA256 之外,还有什么方法可以让我在 python3 中替换这些起始值?

澄清

我有一个有效的 HMAC* h给出。此外,还有一条消息m已被用于(连同密钥k)来生成 h。(h = SHA256(k || m))。

我的任务:我需要找到一种方法来推导另一个 HMAC* h'而不知道k基于m。事实证明,新消息是m' = m + pad(k||m) + a 随机选择的 a

进一步澄清

*:对于“HMAC”,我不是指 RFC 2014 的标准。HMAC 通常“是一种特定类型的消息认证代码 (MAC),涉及加密散列函数和秘密加密密钥。” (维基百科.org/HMAC)。在这种情况下,HMAC 计算为h = SHA256(k || m)其中k是密钥,|| 是串联,m是消息。

标签: python-3.xcryptographysha256hmachashlib

解决方案


首先,SHA256 上下文包含多个参数。在这个解决方案中,其中两个是相关的: 以某种方式代表 SHA256 算法“进度”的状态。最终状态实际上是 SHA256 哈希和。秒参数是以位为单位的总消息长度,将在填充结束时设置。

此外,SHA256 总是使用填充,这意味着在计算最终哈希之前,另一个字节序列p被隐式添加到输入数据中,并且取决于实际输入值。所以假设mySHA256没有使用填充,假设SHA256(x) = mySHA256(x || p(x)) 。

当使用h = SHA256(k || m) = mySHA256(k || m || p)生成给定的 HMAC h时,其中k是密钥,m是消息,h表示 SHA256 上下文的最终状态. 此外,我们有一个依赖于k ||的隐式填充p 。因此,p并不依赖于len(k)而不是k本身,这意味着我们可以在不知道密钥但知道长度的情况下计算p 。

由于我的目标只会在我提供正确的 HMAC h' = SHA256(k || m')时接受我修改后的消息m' = m + a ,所以我现在需要关注这一点。通过知道原始 HMAC h,我可以设置对应于h的 SHA256 上下文的状态。我也知道消息m,并且我知道以位为单位的总消息长度为(len(k) + len(m) + len(p)) * 8,我的总消息长度仅取决于len(k )(不是k!)因为len(p)仅取决于len(k)len(m)。我将遍历一系列len(k),比如 1 - 64。在每个迭代步骤中,我可以只插入我的len(k)值。因此也可以设置整体消息长度(我的 SHA256 上下文的第二个参数)。

当遍历所有键长度时,将有一个值表示实际使用的键的长度。在这种情况下,我有一个 SHA256 上下文,它与原始计算的上下文完全相同。我们现在可以将我们的任意数据a添加到哈希计算中,并创建另一个 HMAC h',它确实依赖于密钥k,而不知道它。h' = SHA256(k || m || p || a)

但是现在,我们必须确保这个 HMAC h'等于那个,目标使用我们的消息m'进行计算。因此,我们将填充p添加到原始消息m的末尾,然后是我们的任意消息a。最后我们有m' = m || p || 一个

由于目标知道密钥以验证输入数据,它可以轻松计算SHA256(k || m') = SHA256(k || m || p || a )* 和 oooops!实际上,这与我们在不知道密钥k的情况下计算的 HMAC h'相同

结果: 我们不能添加完全任意的消息,而是在填充后完全任意的消息。由于填充大部分都是空字节,这可能会干扰我们的攻击,但这取决于每种情况。在我的例子中,Null-Bytes 被忽略了,在我插入的消息之前显示的整个消息长度中只有一个工件。


推荐阅读