【问题标题】:How to set a SHA-256 value to crypto.Hash?如何将 SHA-256 值设置为 crypto.Hash?
【发布时间】:2021-01-15 23:45:12
【问题描述】:

我正在使用 Node.JS 和 crypto 模块。我有一个十六进制字符串中的 SHA-256 哈希,并想从中创建一个 crypto.Hash 实例。我只找到了对输入字符串本身进行哈希处理的方法,但没有找到更新或create 新哈希的方法。我是否遗漏了文档中的某些内容?

我正在寻找类似的东西(不过对于 UUID):

crypto.Hash.from("sha256", "hex", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592")

【问题讨论】:

    标签: node.js cryptography


    【解决方案1】:

    通常没有多少图书馆可以满足您的要求。当然有一些库可以检索和恢复内部状态,例如 Bouncy Castle,但到目前为止我还没有在任何 JavaScript 库中看到它。不过,它会很容易创建。

    确实,512 位的 256 位(总)中间值 每个块 将在最后一个块被散列后用作最终输出。因此,如果您可以“恢复”这些值(即将它们置于状态),那么您可以在此之后继续散列。

    但这可能没那么有用,因为这些值已经包含填充和消息大小,在块末尾编码为 64 位表示。因此,如果您在那之后继续散列,则可能会再次包含该填充和长度,但现在具有不同的值。


    有时在智能卡中使用的一个技巧是在要散列的最后一个数据之前上传中间值(包括散列的位数),并让智能卡执行填充,长度编码以及最终的哈希块操作。这通常在大量数据的签名计算期间执行(因为您确实不想将整个文档发送到智能卡)。

    如果你问我,这很愚蠢,直接使用预先计算的哈希值进行签名是前进的方向。或者确保对大量数据进行预散列,然后对散列进行签名(包括另一遍散列)——这样无需特殊技巧就可以避免整个问题。

    【讨论】:

      【解决方案2】:

      以下小示例代码将字符串散列为 base64 和十六进制字符串编码。

      这是输出:

      buf: The quick brown fox jumps over the lazy dog
      sha256 (Base64): 16j7swfXgJRpypq8sAguT41WUeRtPNt2LQLQvzfJ5ZI=
      sha256 (hex): d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
      

      代码:

      var crypto = require('crypto');
      const plaintext = 'The quick brown fox jumps over the lazy dog';
      const buf = Buffer.from(plaintext, 'utf8');
      console.log('buf: ' + buf);
      const sha256Base64 = crypto.createHash('sha256').update(buf).digest('base64');
      console.log('sha256 (Base64): ' + sha256Base64);
      const sha256Hex = crypto.createHash('sha256').update(buf).digest('hex');
      console.log('sha256 (hex): ' + sha256Hex);
      

      编辑:我误解了这个问题,任务是运行几个 SHA-256 更新调用(例如,针对不同的字符串)并接收(中间)结果。稍后,此结果应用作“输入”,并且应通过更多更新调用进行散列处理,最后由“final”/“digest”完成以获得所有部分的最终 sha-256 值。

      不幸的是,似乎没有办法,因为中间值是最终值,并且(再次)似乎没有回头路,因为最终/摘要调用进行了额外的计算(与底层的 Merkle-Damgård 构造有关)。唯一的方法是使用自己编写的SHA-256函数并保存所有内部寄存器的状态,继续时重置寄存器并最终获得最终值。

      建议获取 sha-256 实现的源代码并保存所有使用变量的内部状态。继续时,您需要恢复这些变量并运行下一个更新调用。我查看了一些(Java)imps,对我来说看起来并不难。

      【讨论】:

      • 谢谢!但这只是展示了如何散列一个字符串。就我而言,我有一个 sha 作为 input 字符串
      • 好的,你确实有一个十六进制字符串格式的哈希 - 想要你处理这个值吗?我不明白你的“创建一个 crypto.Hash 实例”
      • 填充/恢复 crypto.Hash 对象,以便我可以继续调用 update(..) 函数
      • 感谢您的更新,现在我明白了。例如您正在散列 3 个字符串,获取一个中间值 (sha-256),存储该值并尝试继续使用该值以对其他 2 个字符串进行更新调用 -> 以获得 5 个字符串的最终值。
      • 不幸的是,似乎没有办法,因为中间值是最终值,并且(再次)似乎没有办法回来,因为最终/摘要调用进行了额外的计算(与底层[Merkle-Damgård结构](en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd_construction)。唯一的方法是使用自己编写的SHA-256函数并保存所有内部寄存器的状态,继续时重置寄存器并最终获得最终值。好祝你好运!
      猜你喜欢
      • 2013-09-23
      • 2021-11-27
      • 2012-12-31
      • 1970-01-01
      • 2012-08-09
      • 1970-01-01
      • 2014-04-02
      • 2021-05-09
      • 2021-01-22
      相关资源
      最近更新 更多