Tom*_*mmy 12 utf-8 hmac non-ascii-characters node.js node-crypto
当我尝试加密的文本具有重音字符(例如ä,ï,ë)时,我遇到了在NodeJS中生成正确签名(使用crypto.js)的问题
generateSignature = function (str, secKey) {
var hmac = crypto.createHmac('sha1', secKey);
var sig = hmac.update(str).digest('hex');
return sig;
};
Run Code Online (Sandbox Code Playgroud)
如果'str'不包含重音字符(如ä,ï,ë等字符),则此函数将返回正确的HMAC签名.如果文本中存在重音字符,则不会返回正确的HMAC.重音字符在UTF8编码中有效,所以我不知道为什么加密有问题.可能是我需要以某种方式告诉加密我正在签署utf8编码文本,但我不知道如何做到这一点.
这篇文章中描述了完全相同的问题:带有重音的NodeJS hmac摘要问题 然而,帖子本身以及答案对我来说没有意义(因为他们传递他们想要加密的数据,秘密密钥应该在哪里走).
以下是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
Run Code Online (Sandbox Code Playgroud)
输出::
西格:39c9f1a6094c76534157739681456e7878557f58
预计:094b2ba039775bbf970a58e4a0a61b248953d30b
谢谢
Jon*_*ski 19
crypto通常使用模块使用的默认编码'binary'.因此,您必须'utf-8'通过a 指定Buffer将其用作编码:
var sig = hmac.update(new Buffer(str, 'utf-8')).digest('hex');
Run Code Online (Sandbox Code Playgroud)
这就是另一个问题的答案所展示的,仅仅是关键:
var hmac = crypto.createHmac('sha1', new Buffer(secKey, 'utf-8'));
Run Code Online (Sandbox Code Playgroud)
您还可以使用Buffer查看差异:
new Buffer('äïë', 'binary')
// <Buffer e4 ef eb>
new Buffer('äïë', 'utf-8')
// <Buffer c3 a4 c3 af c3 ab>
Run Code Online (Sandbox Code Playgroud)
[ 编辑 ]
运行您提供的示例代码,我得到:
Sig: 094b2ba039775bbf970a58e4a0a61b248953d30b
Expected: 094b2ba039775bbf970a58e4a0a61b248953d30b
Run Code Online (Sandbox Code Playgroud)
并且,稍微修改它,我得到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');
Run Code Online (Sandbox Code Playgroud)