【问题标题】:Node JS crypto, cannot create hmac on chars with accents节点 JS 加密,无法在带有重音符号的字符上创建 hmac
【发布时间】:2012-08-25 02:22:36
【问题描述】:

当我尝试加密的文本包含重音字符(例如ä、ï、ë)时,我在 NodeJS 中生成正确签名(使用 crypto.js)时遇到问题

generateSignature = function (str, secKey) { 
 var hmac = crypto.createHmac('sha1', secKey);
 var sig = hmac.update(str).digest('hex');
 return sig;
};

如果 'str' 不包含重音字符(如 ä、ï、ë 等字符),此函数将返回正确的 HMAC 签名。如果文本中存在重音字符,则不会返回正确的 HMAC。重音字符在 UTF8 编码中有效,所以我不知道为什么加密对它们有问题。可能是我需要以某种方式告诉 crypto 我正在签署 utf8 编码的文本,但我不知道该怎么做。

这篇文章描述了完全相同的问题:NodeJS hmac digest issue with accents 但是,帖子本身以及答案对我来说没有意义(因为他们将要加密的数据传递到密钥应该去的地方)。

这里是 str 和 secKey 硬编码值的代码版本:

  var crypto = require('crypto');

  str="äïë";  
  secKey="secret"; 
  var hmac = crypto.createHmac('sha1', secKey);
  var sig = hmac.update(new Buffer(str, 'utf8')).digest('hex');
  console.log("Sig:      " + sig);
  console.log("Expected: 094b2ba039775bbf970a58e4a0a61b248953d30b"); 
  // "Expected" was generated using http://hash.online-convert.com/sha1-generator

输出::

信号:39c9f1a6094c76534157739681456e7878557f58

预期:094b2ba039775bbf970a58e4a0a61b248953d30b

谢谢

【问题讨论】:

  • 随后发现,当我在 Macbook 上运行完全相同的脚本时,上面的测试返回了一个匹配的“预期”值 - 之前一直在 Windows 上运行

标签: node.js utf-8 hmac non-ascii-characters node-crypto


【解决方案1】:

crypto 模块使用的默认编码通常是'binary'。因此,您必须通过 Buffer 指定 'utf-8' 才能将其用作编码:

var sig = hmac.update(new Buffer(str, 'utf-8')).digest('hex');

这就是 the answer for the other question 所展示的,只是为了关键:

var hmac = crypto.createHmac('sha1', new Buffer(secKey, 'utf-8'));

您也可以使用Buffer查看差异:

new Buffer('äïë', 'binary')
// <Buffer e4 ef eb>

new Buffer('äïë', 'utf-8')
// <Buffer c3 a4 c3 af c3 ab>

[编辑]

运行您提供的示例代码,我得到:

Sig:      094b2ba039775bbf970a58e4a0a61b248953d30b
Expected: 094b2ba039775bbf970a58e4a0a61b248953d30b

并且,稍微修改一下,我得到true

var crypto = require('crypto');

function sig(str, key) {
  return crypto.createHmac('sha1', key)
    .update(new Buffer(str, 'utf-8'))
    .digest('hex');
}

console.log(sig('äïë', 'secret') === '094b2ba039775bbf970a58e4a0a61b248953d30b');

【讨论】:

  • 谢谢,但这并没有解决问题,我实际上已经尝试过了,我也尝试将 str 转换为缓冲区,但也没有用。正如你所说,createHmac 没有“编码”参数,因此这一行中的 'utf8' 参数: var hmac = crypto.createHmac('sha1', new Buffer(secKey, 'utf-8'));
  • @Tommy 你有没有一个例子可以分享你的期望与从特定输入中得到什么?
  • 再次感谢,我刚刚意识到我在 mac 上运行时得到了预期的输出,但在 windows 上却没有
  • 认为您可能是对的 Jonathan,str 中的文本在 Mac 上打开时看起来不同。感谢您的所有帮助
  • @Sushil 作为一个正式问题可能值得提出。但是,简而言之,key 只是第二个 StringBuffer 用作“加密密钥”以及“消息”或data计算哈希。 Security.SE 上有一篇很好的关于 HMAC 的文章:security.stackexchange.com/a/20301。而且,维基百科的文章可以帮助解释如何使用keyen.wikipedia.org/wiki/HMAC
猜你喜欢
  • 1970-01-01
  • 2013-07-19
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
  • 2020-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多