node.js 如何解密 HMAC?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14218925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I decrypt a HMAC?
提问by ThomasReggi
I can make an HMAC using the following:
我可以使用以下方法制作 HMAC:
var encrypt = crypto.createHmac("SHA256", secret).update(string).digest('base64');
I am trying to decrypt an encoded HMAC with the secret:
我正在尝试使用秘密解密编码的 HMAC:
var decrypt = crypto.createDecipher("SHA256", secret).update(string).final("ascii");
The following was unsuccessful. How can I decrypt a HMAC with the key?
以下是不成功的。如何使用密钥解密 HMAC?
I get the following error:
我收到以下错误:
node-crypto : Unknown cipher SHA256
crypto.js:155
return (new Decipher).init(cipher, password);
^
Error: DecipherInit error
回答by CodesInChaos
HMAC is a MAC/keyed hash, not a cipher. It's not designed to be decrypted. If you want to encrypt something, use a cipher, like AES, preferably in an authenticated mode like AES-GCM.
HMAC 是 MAC/keyed hash,而不是密码。它不是为解密而设计的。如果您想加密某些东西,请使用密码,例如 AES,最好使用 AES-GCM 等经过身份验证的模式。
The only way to "decrypt" is guessing the whole input and then comparing the output.
“解密”的唯一方法是猜测整个输入,然后比较输出。
回答by ThomasReggi
Again to reiterate hashes aren't designed to be decrypted. However once you have a hash you can check any string is equal to that hash by putting it through the same encryption with the same secret.
再次重申散列不是为了解密而设计的。然而,一旦你有了一个散列,你就可以检查任何字符串是否等于该散列,方法是将它通过相同的加密并使用相同的秘密。
var crypto = require('crypto')
var secret = 'alpha'
var string = 'bacon'
var hash = crypto.createHmac('SHA256', secret).update(string).digest('base64');
// => 'IbNSH3Lc5ffMHo/wnQuiOD4C0mx5FqDmVMQaAMKFgaQ='
if (hash === crypto.createHmac('SHA256', secret).update(string).digest('base64')) {
console.log('match') // logs => 'match'
} else {
console.log('no match')
}
Seems obvious, but very powerful.
看起来很明显,但非常强大。
回答by mekwall
As already been stated by CodesInChaos, HMAC with SHA256 can only be used to hash a value, which is a one-way trip only. If you want to be able to encrypt/decrypt you will have to use a cipher, such as aesor des.
正如CodesInChaos已经指出的那样,带有 SHA256 的 HMAC 只能用于散列一个值,这只是一种单程旅行。如果您希望能够加密/解密,则必须使用密码,例如aes或des。
Example on how encryption/decryption:
关于如何加密/解密的示例:
const crypto = require("crypto");
// key and iv
var key = crypto.createHash("sha256").update("OMGCAT!", "ascii").digest();
var iv = "1234567890123456";
// this is the string we want to encrypt/decrypt
var secret = "ermagherd";
console.log("Initial: %s", secret);
// create a aes256 cipher based on our password
var cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
// update the cipher with our secret string
cipher.update(secret, "ascii");
// save the encryption as base64-encoded
var encrypted = cipher.final("base64");
console.log("Encrypted: %s", encrypted);
// create a aes267 decipher based on our password
var decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
// update the decipher with our encrypted string
decipher.update(encrypted, "base64");
console.log("Decrypted: %s", decipher.final("ascii"));
Note: You have to save the cipher/decipher into their own variable, and also make sure not to chain .finalafter .update.
注意:您必须将 cipher/decipher 保存到它们自己的变量中,并确保不要.final在.update.
If you want to know what ciphers are available on your system, use the following command:
如果您想知道系统上可用的密码,请使用以下命令:
openssl list-cipher-algorithm
回答by KK.
Clean-up of code for a Minimalist View and removal of clutter: note: IIFE runnable in node repl "As Is"
清理极简视图的代码并清除杂乱:注意:IIFE 可在节点 repl 中“按原样”运行
!function(){
const crypto = require("crypto");
// key
var key = crypto.createHash("sha256").digest();
// this is the string we want to encrypt/decrypt
var secret = "ermagherd";
console.log("Initial: %s", secret);
// create a aes256 cipher based on our password
var cipher = crypto.createCipher("aes-256-cbc", key);
// update the cipher with our secret string
cipher.update(secret);
// save the encryption
var encrypted = cipher.final();
console.log("Encrypted: %s", encrypted);
// create a aes267 decipher based on our password
var decipher = crypto.createDecipher("aes-256-cbc", key);
// update the decipher with our encrypted string
decipher.update(encrypted);
console.log("Decrypted: %s", decipher.final()); //default is utf8 encoding final("utf8") not needed for default
}()
/* REPL Output
Initial: ermagherd
Encrypted: T)??l?????,?'
Decrypted: ermagherd
true
*/

