web-dev-qa-db-ja.com

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
12
ThomasReggi

HMACはMAC /キー付きハッシュであり、暗号ではありません。復号化するようには設計されていません。何かを暗号化する場合は、AESなどの暗号を使用し、できればAES-GCMなどの認証モードで使用します。

「復号化」する唯一の方法は、入力全体を推測してから出力を比較することです。

45
CodesInChaos

繰り返しになりますが、ハッシュは解読されるようには設計されていません。ただし、ハッシュを取得したら、同じシークレットを使用して同じ暗号化を行うことにより、任意の文字列がそのハッシュと等しいことを確認できます。

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

明らかなようですが、非常に強力です。

22
ThomasReggi

CodesInChaos ですでに述べたように、SHA256を使用したHMACは、値のハッシュにのみ使用できます。これは片道のみです。暗号化/復号化したい場合は、aesdesなどの暗号を使用する必要があります。

暗号化/復号化の例:

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
3
mekwall