【问题标题】:crypto createHMAC output differs according to nodejs version加密 createHMAC 输出因 nodejs 版本而异
【发布时间】:2017-08-06 14:49:59
【问题描述】:

我在升级节点版本时遇到了加密模块问题。创建的 HMAC 取决于节点的版本。您将在下面找到重现问题的代码。

如果我将密钥编码为 BASE64(或任何),则 HMAC 不依赖于 node.js 版本。

如果我将其编码为二进制,如果我更改我的 node.js 版本,HMAC 会有所不同。

[编辑]根据Why crypto.createHash returns different output in new version?我在调用update函数时添加了编码

代码sn-p

"use strict";

const crypto = require('crypto');

console.log(process.version);

let key = '5ece799aa73a7a8e687876f8e0eabe2e200b967ef5728d845f72fc9ea27dbcd90cd4e06e8bc90d823ac8a54ce91f68ca37fc2e7bbf3f5ef9d82b4c6b938f1936';

let _key64 = (new Buffer(key, 'hex')).toString('base64');
console.log("B64 KEY: "+crypto.createHmac('sha512', _key64).update("hey", "binary").digest('hex').toUpperCase());

let _keyBin = (new Buffer(key, 'hex')).toString('binary');
console.log("BIN KEY: "+crypto.createHmac('sha512', _keyBin).update("hey", "binary").digest('hex').toUpperCase());

使用 2 个版本的 node.js 输出如下

v5.6.0
B64 KEY: 0DC11C737E575B17DD575042F8F372E3D63A86C3B56C06FB74C9B0AB8E96A5FC8A2DC33667280DC5B306C93AA3DECBAF0D8EDE56F3666C11BFC25A70CFC027D0
BIN KEY: E5A9F813D9AA64A6791BEA91035553FFC730DBE635D0CE7AC722C0195DFDD77A969323FDDFB4E5054E59073DAE9B9BF00CFF73CF20F2FACEE01F79F25E7B9303
v8.1.4
B64 KEY: 0DC11C737E575B17DD575042F8F372E3D63A86C3B56C06FB74C9B0AB8E96A5FC8A2DC33667280DC5B306C93AA3DECBAF0D8EDE56F3666C11BFC25A70CFC027D0
BIN KEY: 6F089BCA7A24BF6C3F8E0F75349C8B446C4E69336CF41AA7A390C9B17086417E475545197B0312B4D9240A9F0388CA8722ADCF04BFD554321290EBBCD61F800E

注意:这是这个问题的缩小范围:HMAC changes according to node version (paybox module)

顺便说一句,如果我这样做了

const key = '5ece799aa73a7a8e687876f8e0eabe2e200b967ef5728d845f72fc9ea27dbcd90cd4e06e8bc90d823ac8a54ce91f68ca37fc2e7bbf3f5ef9d82b4c6b938f1936'
const bkey = (new Buffer(key, 'hex')).toString('binary');
console.log((new Buffer(bkey, 'binary')).toString('hex'));

没问题,无论节点的版本如何,我都会获得相同的密钥5ece799aa73a7a8e687...

【问题讨论】:

  • 如果我将 "BIN KEY: ....update("hey") 更改为 "BIN KEY: ....update("hey", "utf-8") 以回答 stackoverflow.com/questions/45530779/… 中的 cmets,这将给出相同的结果
  • 尝试进一步缩小范围。您使用这两种方法对内容等进行编码。您应该比较 作为二进制 的结果,例如在两个运行时中的运行之间重新编码为十六进制。哈希算法本身不太可能,但 PHP 和 JavaScript 再一次让我惊叹不已。
  • @MaartenBodewes 我已按照建议在问题(底部)中添加了缩小范围。传递的缓冲区似乎是一致的,因为 hex -> binary -> hex 是稳定的。谜团还活着
  • 如果您对"hey"(消息)使用空字符串或二进制值会怎样?如果它不是密钥,则它必须是其他东西(尽管密钥/消息编码的内部处理也可能是一个问题)。
  • 我怀疑github.com/nodejs/node/commit/… 可能是造成这种差异的原因。字符串转换为缓冲区的方式在createHmac 内部发生了变化。如果您直接使用缓冲区(即let _keyBin = new Buffer(key, 'hex');,我认为您会在两个版本中得到相同的结果。

标签: node.js encoding cryptography hmac node-crypto


【解决方案1】:

感谢@matt:总结他的评论

由于https://github.com/nodejs/node/commit/b010c8716498dca398e61c388859fea92296feb3,最好通过删除.toString('binary') 将缓冲区传递给crypto

所以这个

"use strict";

const crypto = require('crypto');

console.log(process.version);
let key = '5ece799aa73a7a8e687876f8e0eabe2e200b967ef5728d845f72fc9ea27dbcd90cd4e06e8bc90d823ac8a54ce91f68ca37fc2e7bbf3f5ef9d82b4c6b938f1936';

let _key64 = (new Buffer(key, 'hex')).toString('base64');
console.log("B64 KEY: "+crypto.createHmac('sha512', _key64).update("hey", "binary").digest('hex').toUpperCase());

let _keyBin = (new Buffer(key, 'hex'));
console.log("BIN KEY: "+crypto.createHmac('sha512', _keyBin).update("hey", "binary").digest('hex').toUpperCase());

有效(当然)

v5.6.0
B64 KEY: 0DC11C737E575B17DD575042F8F372E3D63A86C3B56C06FB74C9B0AB8E96A5FC8A2DC33667280DC5B306C93AA3DECBAF0D8EDE56F3666C11BFC25A70CFC027D0
BIN KEY: E5A9F813D9AA64A6791BEA91035553FFC730DBE635D0CE7AC722C0195DFDD77A969323FDDFB4E5054E59073DAE9B9BF00CFF73CF20F2FACEE01F79F25E7B9303
v8.1.4
B64 KEY: 0DC11C737E575B17DD575042F8F372E3D63A86C3B56C06FB74C9B0AB8E96A5FC8A2DC33667280DC5B306C93AA3DECBAF0D8EDE56F3666C11BFC25A70CFC027D0
BIN KEY: E5A9F813D9AA64A6791BEA91035553FFC730DBE635D0CE7AC722C0195DFDD77A969323FDDFB4E5054E59073DAE9B9BF00CFF73CF20F2FACEE01F79F25E7B9303

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多