我正在努力遵循https://en.wikipedia.org/wiki/SHA-2中所述的SHA-2加密函数。
我正在研究说:
我不明白最后两行。添加K' 0'位是512.我应该如何在Java代码中实现它?
答案 0 :(得分:1)
首先,应该明确"字符串"所谈到的不是Java String
而是一个字符串。这些算法是基于二进制/位的。实现通常不处理位而是字节。所以有一个转换阶段,你应该看到字节而不是位。
SHA-512以512位(SHA-224/256)或1024位(SHA-384/512)的块运行。所以基本上你有一个64或128字节的缓冲区,你正在填充它之前。您也可以直接将数据缓存在32位int
字段(SHA-224/256)或64位long
字段中,因为这是操作的字大小。
现在填充程序相对简单。填充称为位填充。由于它在big-endian模式下使用(幸运的是SHA-2使用它而不是SHA-3中的braindead little endian模式),填充由一个字节中最高位的一个位组成,其余部分由零'第这使得(byte) 0x80
的值必须放在缓冲区中。
如果由于缓冲区已满而无法创建此填充,则必须处理上一个块,然后将现有缓冲区的第一位设置为(byte) 0x80
。在较新的Java中,您也可以使用(byte) 0b1_0000000
字节,这更明确。
现在您只需添加零,直到剩下8到16个字节,这取决于所使用的哈希输出大小。如果没有足够的字节,则填充直到结束,处理块,并重新开始填充零字节,直到再次剩下8或16个字节为止。
现在最后你必须在你剩下的8或16个字节中编码位的数量。因此,将输入乘以8,并确保使用与Java中预期相同的方式对这些字节进行编码,尽可能使用最低有效位。如果您不想自己编程,可能需要使用https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#putLong-long-
。你可能会遗忘任何超过2 ^ 56字节的东西,所以如果你有SHA-384 / SHA-512,那么只需将前八个字节设置为零。
除此之外,您仍然需要处理最后一个块,然后根据特定输出大小的需要使用左侧的字节数。