Python 具有起始值的 hashlib SHA256

Python hashlib SHA256 with starting value

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

我的问题是基于实现的: 为了推动这种攻击,我需要用现有的 HMAC* 替换默认的 SHA256 起始值(h0 到 h7)。由于我没有key,直接push原始数据是不行的

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

澄清

我有一个有效的 HMAC* h。 此外,还有一条消息 m 已被使用(与密钥 k 一起)生成 h。 (h = SHA256(k || m)).

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

进一步说明

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

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

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

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

因为我的目标只会在我提供正确的 HMAC h' = SHA256(k || m '),我现在需要关注这一点。通过知道原来的HMACh,我可以设置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)[= 的值68=]。所以也可以设置整体消息长度(我的 SHA256 上下文的第二个参数)。

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

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

由于目标知道密钥以验证输入数据,因此可以轻松计算 SHA256(k || m') = SHA256(k || m || p || a )* 糟糕!事实上,这与我们在不知道密钥 k

的情况下计算的 HMAC h' 的哈希和相同

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