节点JS加密,无法在带重音的字符上创建hmac

时间:2020-11-24 18:27:05

I am having an issue generating the correct signature in NodeJS (using crypto.js) when the text I am trying to encrypt has accented characters (such as ä,ï,ë)

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

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

This function will return the correct HMAC signature if 'str' contains no accented characters (chars such as ä,ï,ë). If there are accented chars present in the text, it will not return the correct HMAC. The accented characters are valid in UTF8 encoding so I dont know why crypto has a problem with them. It may be the case that I need to somehow tell crypto that I am signing utf8 encoded text, but I don't know how to do this.

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

The exact same problem is described in this post: NodeJS hmac digest issue with accents However, the post itself, as well as the answer, do not make sense to me (as they are passing the data they want to encrypt where the secret key should go).

这篇文章中描述了完全相同的问题:带口音的NodeJS hmac摘要问题然而,帖子本身以及答案对我来说没有意义(因为他们传递他们想要加密的数据,秘密密钥应该在哪里走)。

Here is a version of the code with hard coded values for str and secKey:

以下是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

Output::

输出::

Sig: 39c9f1a6094c76534157739681456e7878557f58

Sig:39c9f1a6094c76534157739681456e7878557f58

Expected: 094b2ba039775bbf970a58e4a0a61b248953d30b

预计:094b2ba039775bbf970a58e4a0a61b248953d30b

Thanks

谢谢

1 个解决方案

#1


17  

The default encoding used by the crypto module is usually 'binary'. So, you'll have to specify 'utf-8' via a Buffer to use it as the encoding:

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

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

That's what the answer for the other question was demonstrating, just for the key:

这就是另一个问题的答案所展示的,仅仅是关键:

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

You can also use Buffer to view the differences:

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

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

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

[Edit]

[编辑]

Running the example code you provided, I get:

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

Sig:      094b2ba039775bbf970a58e4a0a61b248953d30b
Expected: 094b2ba039775bbf970a58e4a0a61b248953d30b

And, modifying it slightly, I get 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');

#1


17  

The default encoding used by the crypto module is usually 'binary'. So, you'll have to specify 'utf-8' via a Buffer to use it as the encoding:

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

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

That's what the answer for the other question was demonstrating, just for the key:

这就是另一个问题的答案所展示的,仅仅是关键:

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

You can also use Buffer to view the differences:

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

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

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

[Edit]

[编辑]

Running the example code you provided, I get:

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

Sig:      094b2ba039775bbf970a58e4a0a61b248953d30b
Expected: 094b2ba039775bbf970a58e4a0a61b248953d30b

And, modifying it slightly, I get 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');