SHA 2 Hashing和Java的问题

时间:2017-11-11 03:46:02

标签: security hash cryptography sha

我正在努力遵循https://en.wikipedia.org/wiki/SHA-2中所述的SHA-2加密函数。

我正在研究说:

  • 从长度为L位的原始消息开始,附加单个' 1'位;
  • 追加K' 0'比特,其中K是最小数> = 0,使得L + 1 + K + 64是512的倍数
  • 将L附加为64位大端整数,使总后处理长度为512位的倍数。

我不明白最后两行。添加K' 0'位是512.我应该如何在Java代码中实现它?

1 个答案:

答案 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,那么只需将前八个字节设置为零。

除此之外,您仍然需要处理最后一个块,然后根据特定输出大小的需要使用左侧的字节数。