问题描述
我一直在挑选 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
方法来存储和操作 list
和 0
的 Python 1
以表示一个 32 位的字,而不是操作实际的位和字节(我这样做的目的只是为了了解 SHA-256
和按位运算是如何工作的)。所以,我对 SHA-256
的工作原理有很好的理解,但我一直无法弄清楚 0x80
在 0x01
中的用法:
message.append(0x80)
-
0x80
是128
的十六进制表示,可以用 8 位(10000000
)表示。 -
0x01
是1
的十六进制表示,可以仅用一位 (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 (将#修改为@)