在Node中从对象生成一致的sha256哈希值

3

我有一个对象,想在Node中使用sha256进行哈希处理。对象的内容是简单的Javascript类型。为了举例说明,假设如下:

var payload = {
    "id": "3bab3f00-7d55-11e7-9b0a-4c32759242a5",
    "foo": "a message",
    "version": 7,
};

我是这样创建哈希值的:

const crypto = require('crypto');
var hash = crypto.createHash('sha256');
hash.update( ... ).digest('hex');

问题是,要传递什么来进行更新? 加密文档 中指出可以传递 ` | | | ` ,这似乎表明对象不适合传递。
无法使用 `toString()`,因为它会输出 `"[object Object]"`。可以使用 JSON.stringify,但我在其他地方读到过,对于相同的输入,stringify 的输出不能保证是确定性的。
还有其他选择吗? 我不想从 NPM 下载软件包。

你能解释一下为什么要这样做吗?这可能会提供更好的思路。 - Paul
我猜想任何人想要哈希任何东西的原因都是相同的...为了创建一个可重复的对象内容摘要,该摘要a) 与不同对象的哈希值不同,并且b) 难以伪造。 - Kevin Burke
这是我在简单的谷歌搜索后找到的几个npm模块之一。如果它们不能满足您的需求,它们可能会给您提供一些想法。https://github.com/puleos/object-hash/blob/master/readme.markdown - Paul
为什么你不想从npm下载东西? - ralphtheninja
https://github.com/mirkokiefer/canonical-json - Maarten Bodewes
1个回答

4
正确的术语是“规范化(canonical)”,行为称为“规范化(canonicalization)”(我假设这里是EN-US),你可以找到一个产生规范输出的stringify,链接在此here
请注意,您必须确保输出也具有正确的字符集(应优先选择UTF-8)和换行符。不应存在杂乱数据,例如字节顺序标记或NUL终止字符串足以使哈希值无效。
之后,您可以将其作为string传递,我想。
当然,您可以使用任何规范编码。请注意,XML已定义了XML-digsig,其中包含规范化在签名生成和签名期间,这意味着如果XML代码被更改(当然不会更改结构或内容,但空格/缩进无关紧要),验证仍将成功。
我仍然建议在库的实现甚至版本更新之间进行回归测试。

1
请注意,JavaScript和JSON是为了方便使用而创建的,并不严格。然而,安全和加密需要严格的控制。因此,您将需要进行更多的测试来创建一个安全的实现。我并不是说这是好还是坏,只是它就是这样。 - Maarten Bodewes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接