3

私のPHP暗号化は次のようになります。

<?
$salt = '…';
$data = '…';

$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB), MCRYPT_RAND);
$ciphered = trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $data, MCRYPT_MODE_ECB,$iv)));

上記のコードの結果を次のように解読しようとしています。

ciphered = '…';
crypto = require('crypto');
salt = crypto.createHash('md5').update('…').digest('hex');
iv = '0123456789123455';
decipher = crypto.createDecipheriv('aes-256-cbc', salt, iv);
deciphered = decipher.update(ciphered, 'base64');
deciphered += decipher.final('utf-8');

このコードの結果は次のとおりです。TypeError: DecipherFinal fail

4

1 に答える 1

4

私が見るいくつかの問題:

  1. 動作モードの不一致。CFB(暗号フィードバック)動作モードのIVを生成し、実際に暗号化するときのモードとしてECB(電子コードブック-推奨されません。理由についてはそのwiki記事の画像を確認してください)を使用し、 CBC(暗号ブロック連鎖)モード。1つのモード(おそらくCBC)に固執する必要があります。これを行うには、復号化側aes-256-cbcを維持し、暗号化側を作成しますMCRYPT_MODE_CBC

  2. $ salt(実際にはキーです)をmcrypt_encryptハッシュせずに渡しますが、ハッシュし、ドキュメントcrypto.createDecipherivに従って、binaryエンコードされた文字列が必要な場合は16進文字列を返します。両方のキーは同じである必要があり、関数に渡されたときに同じままになるように適切なエンコーディングに従う必要があります。

  3. 暗号化側でIVを生成し、復号化側でIVに固定文字列を使用しているようです。IV(初期化ベクトル)は暗号文と復号化側に通信する必要があります(暗号文と一緒に平文で送信しても問題ありません)。

  4. ドキュメントによると、復号化オブジェクトのメソッドはエンコーディングとしてupdate受け入れられません。base64テキストを別のテキスト(おそらくバイナリエンコーディング)に変換してから、適切なエンコーディングでupdateメソッドに渡す必要があります。base64

  5. PHPのデフォルトの文字セットはISO-8859-1ですが、暗号文をUTF-8文字列として復号化しようとしています。これにより、特に標準ASCIIで使用されている文字以外の文字を使用する場合に問題が発生する可能性があります。PHP側がUTF-8モードで動作していることを確認するか(その方法についてはこのSO回答を確認してください)、入力でASCII文字のみを使用していることを確認する必要があります(ISO-8859-1はASCIIのスーパーセットです)。 )そして「ascii」出力エンコーディングを使用します。

あなたの問題のほとんどは、エンコーディングの問題に要約されます。node.jsのさまざまな種類のエンコーディングについてはよくわからないので、自分で調査する必要がありますが、暗号化プリミティブの問題は簡単に修正できるはずです。mcrypt_encrypt リンクしたドキュメントとドキュメントも必ずお読みください。

于 2013-01-29T05:01:32.097 に答える