SHA - 为什么用 0x80 和 0x01 填充?

问题描述

我一直在挑选 SHA-256 实现的填充部分,取自 this GitHub 存储库:

message = bytearray(data)

length = len(message) * 8
message.append(0x80)
while (len(message) * 8 + 64) % 512 != 0:
    message.append(0x00)

message += length.to_bytes(8,'big')

我已经使用自定义数据结构正确实现了我自己的 SHA-256 方法来存储和操作 list0 的 Python 1 以表示一个 32 位的字,而不是操作实际的位和字节(我这样做的目的只是为了了解 SHA-256 和按位运算是如何工作的)。所以,我对 SHA-256 的工作原理有很好的理解,但我一直无法弄清楚 0x800x01 中的用法

message.append(0x80)
  • 0x80128 的十六进制表示,可以用 8 位(10000000)表示。
  • 0x011 的十六进制表示,可以仅用一位 (1) 表示,但有 7 个 8 位形式的前导零 (00000001 ).

据我了解,当填充消息时,会放置一个 1 位以将消息与填充分开。 1 的前导零不会被截断并导致 1 位,而 0x80 的尾随零会导致额外的零吗?

编辑:

啊,在尝试想出一个例子的同时回答(?)你的问题的美妙之处。

因为 Unicode 字符总是以 8 位的倍数编码,所以 0x80 的尾随零 总是 适合。 SHA-256 中每个 512 位块的末尾保留了 64 位,以位为单位表示消息的长度。剩下 448 (512-64) 位需要由消息和填充来填充。

如果消息长度为 440 位,则剩下 8 位需要通过填充来填充以形成 448 位。 0x80 会负责。

0110......011 + 10000000 + 000......110111000
      ^             ^              ^
message (440)     0x80     len(msg) (64 bits)

这等于 512 (440+8+64=512)。

如果消息长度为 448 位,则剩下 0 位用于填充,这没有任何好处,因为需要 1 位将消息与填充分开。因此,即使您可以添加一个没有尾随零的 1 位,您仍然会超过 512 位 (448+1+64=513)。这使得所需的位数超过了 512 的阈值,这意味着需要另一个消息块。因此,0x80 不会造成零溢出,因为无论如何都需要创建另一个消息块。

此外,我不确定我是如何错过这条明显的信息的,但是 Python bytearray 会将 0x01 存储为 00000001 ,有七个前导零。为什么?嗯……因为它是一个 byte 数组,而字节是 8 位的……哈哈。
因此,如果您尝试使用 0x01 将消息与填充分开,您最终会得到消息位加上 00000001一个字节 ),而不是消息位加上 1 位(不会起作用)。

这是正确的推理吗?

注意:我会添加我自己的答案,但想事先确认我的想法和解释实际上是正确的!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)