web-dev-qa-db-fra.com

Comment décrypter un HMAC?

Je peux créer un HMAC en utilisant ce qui suit:

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

J'essaie de décrypter un HMAC encodé avec le secret:

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

Ce qui suit n'a pas réussi. Comment déchiffrer un HMAC avec la clé?

J'obtiens l'erreur suivante:

node-crypto : Unknown cipher SHA256

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

HMAC est un hachage MAC/à clé, pas un chiffre. Il n'est pas conçu pour être décrypté. Si vous souhaitez chiffrer quelque chose, utilisez un chiffrement, comme AES, de préférence dans un mode authentifié comme AES-GCM.

La seule façon de "décrypter" est de deviner l'entrée entière, puis de comparer la sortie.

45
CodesInChaos

Encore une fois, pour réitérer les hachages, ils ne sont pas conçus pour être décryptés. Cependant, une fois que vous avez un hachage, vous pouvez vérifier que n'importe quelle chaîne est égale à ce hachage en la soumettant au même cryptage avec le même 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')
}

Semble évident, mais très puissant.

22
ThomasReggi

Comme déjà indiqué par CodesInChaos , HMAC avec SHA256 ne peut être utilisé que pour hacher une valeur, qui est un aller simple. Si vous voulez pouvoir crypter/décrypter, vous devrez utiliser un chiffrement, tel que aes ou des.

Exemple sur la façon dont le chiffrement/déchiffrement:

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

Remarque: Vous devez enregistrer le chiffrement/déchiffrement dans leur propre variable, et assurez-vous également de ne pas chaîner .final après .update.

Si vous voulez savoir quels chiffrements sont disponibles sur votre système, utilisez la commande suivante:

openssl list-cipher-algorithm
3
mekwall