SHA 2 哈希和 Java 的问题

Problems with SHA 2 Hashing and Java

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

我正在检查以下行:

最后两行我没看懂。如果我的字符串很短,它的长度在添加 K'0' 位后可以是 512。我应该如何在 Java 代码中实现它?

首先要明确一点,这里所说的"string"并不是JavaString而是一个位串。这些算法基于 binary/bit。该实现通常不会处理位,而是处理字节。所以有一个翻译阶段,您应该看到字节而不是位。

SHA-512 在 512 位 (SHA-224/256) 或 1024 位 (SHA-384/512) 的块中运行。所以基本上你有一个 64 或 128 字节的缓冲区,你在操作之前填充它。您也可以直接将数据缓存在 32 位 int 字段(SHA-224/256)或 64 位 long 字段中,因为这是操作的字长。

现在db2的程序比较简单。填充称为位填充。由于它用于大端模式(SHA-2 幸运地使用它而不是 SHA-3 中的 braindead 小端模式),填充由一个字节中最高位设置的单个位组成,其余填充为零的。这使得必须将值 (byte) 0x80 放入缓冲区。

如果由于缓冲区已满而无法创建此填充,则您将不得不处理前一个块,然后将现在可用缓冲区的第一位设置为 (byte) 0x80。在较新的 Java 中也可以使用 (byte) 0b1_0000000 byte 的方式,这样更显式。

现在您只需添加零,直到剩下 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 然后简单地将前八个字节设置为零。

仅此而已,除了您仍然需要处理最后一个块,然后根据您的特定输出大小从左侧开始使用尽可能多的字节。