Как я могу расшифровать HMAC?

Я могу сделать HMAC, используя следующее:

var encrypt = crypto.createHmac("SHA256", secret).update(string).digest('base64');

Я пытаюсь расшифровать закодированный HMAC с секретом:

var decrypt = crypto.createDecipher("SHA256", secret).update(string).final("ascii");

следующее не удалось. Как расшифровать HMAC с помощью ключа?

Я получаю следующую ошибку:

node-crypto : Unknown cipher SHA256

crypto.js:155
  return (new Decipher).init(cipher, password);
                        ^
Error: DecipherInit error

4 ответов


HMAC является хэшем MAC / keyed, а не шифром. Он не предназначен для расшифровки. Если вы хотите что-то зашифровать, используйте шифр, например AES, предпочтительно в аутентифицированном режиме, например AES-GCM.

единственный способ "расшифровать" - угадать весь вход, а затем сравнить выход.


снова повторить хэши не предназначены для дешифрования. Однако, как только у вас есть хэш, вы можете проверить, что любая строка равна этому хэшу, проведя ее через то же шифрование с тем же секретом.

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')
}

Кажется очевидным, но очень мощный.


как уже было сказано CodesInChaos, HMAC с SHA256 может использоваться только для хэширования значения,которое является односторонним путешествием. Если вы хотите иметь возможность шифровать / расшифровывать, вам придется использовать шифр, такой как aes или des.

пример о том, как шифрование / дешифрование:

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"));

Примечание: Вы должны сохранить шифр / дешифратор в свою собственную переменную, а также убедитесь, что не цепочка .final после .update.

если вы чтобы узнать, какие шифры доступны в вашей системе, используйте следующую команду:

openssl list-cipher-algorithm

очистка кода для минималистского просмотра и удаления беспорядка: Примечание: IIFE runnable в узле 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
*/