MD5-PADDING 在哪个位置开始?

At Which Position MD5-PADDING starts?

我正在尝试实现 MD5 File-Hash,我认为它会在不久的将来完成。目前我需要附加 PADDING 但我不明白它是如何工作的。

示例:我有一个包含 109 字节数据的文件。

//    512 Bit            360 Bit      
//  -------------     -------------    
//  |xxxxxxxxxxx|     |xxxxxx     |     
//  -------------     -------------

将 PADDING 附加到数据时,是否必须如下所示:

//    512 Bit            360 Bit           512 Bit
//  -------------     -------------     ------------- 
//  |xxxxxxxxxxx|     |xxxxxx|1|00|     |00000000|64|
//  -------------     -------------     -------------

或这个

//    512 Bit            512 Bit      
//  -------------     -------------    
//  |xxxxxxxxxxx|     |xxx|1|00|64|     
//  -------------     -------------

还是这个?

//    512 Bit            360 Bit           512 Bit
//  -------------     -------------     ------------- 
//  |xxxxxxxxxxx|     |xxxxxx     |     |10000000|64|
//  -------------     -------------     -------------

我很困惑。在查阅 RFC1321 文本后,如果可以在块内填充,我认为在同一块中使用填充。如果这不合适,则使用新块。

我说得对吗?

编辑:需要更多细节。

填充将附加到哪里? 在最后一个数据位或最后一个数据字节之后?还是这一样?

像这样?

                512 Bit-Block
--------------------------------------------------
|1|1|0|X0000000|                 |0|0|0|0|0|0|0|1|

|0|0|0|00000000|                 |0|0|0|0|0|0|0|0|
|0|0|4|00000000|                 |0|0|0|0|0|0|0|1|
|0|0|6|00000000|    ...          |0|0|0|0|0|0|0|1|
|1|1|8|00000000|                 |0|0|0|0|0|0|0|1|
|1|1|0|00000000|                 |0|0|0|0|0|0|0|1|
|0|1|0|00000000|                 |0|0|0|0|0|0|0|1|
|1|1|0|00000000|                 |0|0|0|0|0|0|0|0|
--------------------------------------------------  
|DATA |PADDING                   | 64 Bit counter|

还是这样?

                512 Bit-Block
--------------------------------------------------
|1|1|0|00000000|                 |0|0|0|0|0|0|0|1|
|0|0|0|00000000|                 |0|0|0|0|0|0|0|0|
|0|0|4|00000000|                 |0|0|0|0|0|0|0|1|
|0|0|6|00000000|    ...          |0|0|0|0|0|0|0|1|
|1|1|8|00000000|                 |0|0|0|0|0|0|0|1|
|1|1|X|00000000|                 |0|0|0|0|0|0|0|1|
|0|1|0|00000000|                 |0|0|0|0|0|0|0|1|
|1|1|0|00000000|                 |0|0|0|0|0|0|0|0|
--------------------------------------------------  
|DATA |PADDING                   | 64 Bit counter|

RFC 对此有明确的定义:

The message is "padded" (extended) so that its length (in bits) is congruent to 448, modulo 512. [...] In all, at least one bit and at most 512 bits are appended.

所以基本上,在添加长度之前,你的最后一个块必须是 448 位长。所以如果你有109字节的数据,872位,你需要在最后一个块后面追加88位:

//    512 Bits           512 Bits     
//  -------------     -------------    
//  |xxxxxxxxxxx|     |xxxxxx10064|     
//  -------------     -------------

其中 100 实际上是单个 1 位后跟 87 0 位,64 是原始消息的长度(872 在你的情况下)。

如果您的消息类似于 960 位长 (512 + 448),那么您将添加整个 512 位块(一个 1 和 511 0),如果它是 959 位长 (512 + 447),那么应该只添加一个 1 位。这是两种极端情况。

注意:也许您不知道 congruent 是什么意思,而这正是您在努力理解 RFC 时遇到的问题:XY 一致模 Z 如果 X % Z == Y.