【问题标题】:Problems with SHA 2 Hashing and JavaSHA 2 哈希和 Java 的问题
【发布时间】:2018-04-24 08:28:21
【问题描述】:

我正在努力遵循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 代码中实现呢?

【问题讨论】:

    标签: security hash cryptography sha


    【解决方案1】:

    首先要明确一点,这里所说的“字符串”不是Java的String,而是位字符串。这些算法是基于二进制/位的。该实现通常不会处理位而是字节。所以有一个翻译阶段,你应该看到字节而不是位。

    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 字节的方式,这更明确。

    现在您只需添加零,直到剩下 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,则只需将前 8 个字节设置为零。

    就是这样,除了您仍然需要处理最后一个块,然后根据您的特定输出大小的需要使用从左边开始的尽可能多的字节。

    【讨论】:

    • 请注意,Bouncy Castle 和 Java 源代码都是现成的。有时它们并不那么容易阅读,所以我一直很好并描述了它。
    猜你喜欢
    • 2014-08-19
    • 1970-01-01
    • 2017-02-26
    • 2014-02-03
    • 1970-01-01
    • 2011-10-14
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多