web-dev-qa-db-ja.com

CryptoJSで文字列を復号化できません

開発したいコードの予備テストとして、CryptoJSを使用してデータをエンコード/デコードしようとしています。これは私が暗号化に使用しているコードです:

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>
var message = "Secret Message";
var key = CryptoJS.enc.Hex.parse('36ebe205bcdfc499a25e6923f4450fa8');
var iv  = CryptoJS.enc.Hex.parse('be410fea41df7162a679875ec131cf2c');

// Encription. Works ok
var encrypted = CryptoJS.AES.encrypt(
        message,key,
        {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }
    );
console.log('encrypted:'+encrypted.ciphertext.toString());
<script>

これは私が復号化に使用する最初のテストです。正常に動作し、3f0e590d2617dc7007b89350bd590409を返します

// Decription. Works ok with "encrypted" parameter
var decrypted = CryptoJS.AES.decrypt(
        encrypted,key,
        {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }
    );
console.log('decrypted:'+decrypted.toString(CryptoJS.enc.Utf8));

encryptedパラメータは、前回のCryptoJS.AES.encryptの呼び出しの結果であることに注意してください。それはオブジェクトです。

私が抱えている問題は、文字列を直接復号化しようとしたときです。

// Decription. It fails with manual data
var manual_data = CryptoJS.enc.Hex.parse('3f0e590d2617dc7007b89350bd590409');
var decrypted = CryptoJS.AES.decrypt(
        manual_data,key,
        {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }
    );
console.log('decrypted, by hand:'+decrypted.toString(CryptoJS.enc.Utf8));

「空の」オブジェクト(上記の例では空の文字列)を返します。 CryptoJS.AES.decryptが必要とするデータがいくつかあるようです。これらのデータは、最初の例の暗号化されたオブジェクトに格納されていますが、2番目の例のwordarrayにはありません。

なぜこれが起こっているのか誰かが知っていますか?

11
Alvaro Maceda

私はしばらくこれをいじっています、そして私はあなたの問題を見つけたと思います。主な問題は、この行encrypted.ciphertext.toString()です。必要なのはencrypted.toString()だけです。

toString関数は、CryptoJSによってこのオブジェクトに対して定義されており、安全に送信できる暗号化されたメッセージを返します。したがって、これを変更すると、次のようになります。

_var encrypted = CryptoJS.AES.encrypt(
  message,
  key,
  {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  }
);
console.log('            encrypted: '+encrypted.toString());
_

これにより、_Pw5ZDSYX3HAHuJNQvVkECQ==_の代わりに_3f0e590d2617dc7007b89350bd590409_が出力されます。 2番目の関数が機能している理由は、encrypted.ciphertext.toString()を使用せず、実際のオブジェクトを使用するだけなので、そのオブジェクトに変更がないためです。最後の1つでは、使用していた間違ったテキストを、ciphertext部分なしで返される新しいテキストに変更しますが、_CryptoJS.enc.Hex.parse_も削除する必要があります。あなたがここで何をしていたのかはよくわかりませんが、それが何かを意味していたかどうかは調査できます。

_var manual_data = 'Pw5ZDSYX3HAHuJNQvVkECQ==';
var decrypted = CryptoJS.AES.decrypt(
  manual_data,
  key,
  {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  }
);
console.log('   decrypted, by hand: '+decrypted.toString(CryptoJS.enc.Utf8));
_

これは正しいものを記録するはずです。

このために JSBin も作成しました。 JSBinを使うのは初めてなので、正しく使ったと思います。

20
DutGRIFF