从PHP解密CryptoJS

时间:2018-10-24 20:13:14

标签: javascript php aes cryptojs

这是我的PHP代码:

$cipher = 'aes-256-cbc';
// 128-bit key
$key = md5('super secret', true);
// 128-bit IV
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($message, $cipher, $key, OPENSSL_RAW_DATA, $iv);

error_log(__FILE__ . __LINE__ . ' key: ' . bin2hex($key));
error_log(__FILE__ . __LINE__ . ' iv: ' . bin2hex($iv));
error_log(__FILE__ . __LINE__ . ' ciphertext: ' . bin2hex($ciphertext));

file_put_contents($courseOutlineFile, bin2hex($iv) . bin2hex($ciphertext));

还有我的Javascript代码,其中res是来自ajax响应的文本,用于读取PHP生成的文件:

var k = CryptoJS.MD5('super secret');
var iv = CryptoJS.enc.Hex.parse(res.substring(0, 32));
var data = CryptoJS.enc.Hex.parse(res.substring(32));

console.log("key: ", CryptoJS.enc.Hex.stringify(k))
console.log("iv: ", CryptoJS.enc.Hex.stringify(iv))
console.log("ciphertext: ", CryptoJS.enc.Hex.stringify(data))

var cipher = CryptoJS.lib.CipherParams.create({
    ciphertext: data
});

var dec = CryptoJS.AES.decrypt(cipher, k, {
    iv: iv,
    mode: CryptoJS.mode.CBC
});
console.log("decrypted:", dec.toString(CryptoJS.enc.Hex));

var json = dec.toString(CryptoJS.enc.Utf8);
console.log("json:", json)

我已经使用比较工具验证了密钥,IV和数据的十六进制值在PHP中是相同的,并且打印到浏览器控制台的内容也相同。它确实可以成功解密(某些东西),但是最后一个console.log语句生成错误:错误:“格式错误的UTF-8数据”。如果我尝试使用Latin1,则会导致一堆不可打印的字符。

我正在加密的$ message变量是数组上json_encode的输出。

有人知道我想念什么吗?

这些是解密结果的前80个十六进制数字,整个东西还不到28k十六进制数字。

  

20a290156abf2855f2c3344a2d9cf7dc84c5c02b1a48a03f18aa8a5054f650dd5517b25b6582c72d

这是一个完整的例子:

<?php
ini_set('display_errors', 1);

$jsonObj = [
  'el1' => 'val1',
  'ar1' => [
    'el2' => 'val2',
    'el3' => 'val3',
  ],
];
$message = json_encode($jsonObj);
echo $message . '<br>';
$cipher = 'aes-256-cbc';
// 128-bit key
$key = md5('super secret', true);
// 128-bit IV
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($message, $cipher, $key, OPENSSL_RAW_DATA, $iv);

echo ' key: ' . bin2hex($key) . '<br>';
echo ' iv: ' . bin2hex($iv) . '<br>';
echo ' ciphertext: ' . bin2hex($ciphertext) . '<br>';

echo bin2hex($iv) . bin2hex($ciphertext);

输出:

{"el1":"val1","ar1":{"el2":"val2","el3":"val3"}}
key: 5f1903f5f2cb32acb4c1dcae9e30d374
iv: bfdb765d1ca4734c5748ffb9883dd15c
ciphertext: 
02717027440040375f7e0dbea69e77783949d3c160529eef0b9d59a751a2a312fa137a5034f6f4c9f89a348ef3f96fce40c8afe0c8a20a2f7a2535417cca2dd2
bfdb765d1ca4734c5748ffb9883dd15c02717027440040375f7e0dbea69e77783949d3c160529eef0b9d59a751a2a312fa137a5034f6f4c9f89a348ef3f96fce40c8afe0c8a20a2f7a2535417cca2dd2

和Javascript:

res = 'bfdb765d1ca4734c5748ffb9883dd15c02717027440040375f7e0dbea69e77783949d3c160529eef0b9d59a751a2a312fa137a5034f6f4c9f89a348ef3f96fce40c8afe0c8a20a2f7a2535417cca2dd2';
var k = CryptoJS.MD5('super secret');
var iv = CryptoJS.enc.Hex.parse(res.substring(0, 32));
var data = CryptoJS.enc.Hex.parse(res.substring(32));

console.log("key: ", CryptoJS.enc.Hex.stringify(k))
console.log("iv: ", CryptoJS.enc.Hex.stringify(iv))
console.log("ciphertext: ", CryptoJS.enc.Hex.stringify(data))

var cipher = CryptoJS.lib.CipherParams.create({
    ciphertext: data
});

var dec = CryptoJS.AES.decrypt(cipher, k, {
    iv: iv,
    mode: CryptoJS.mode.CBC
});
console.log("dec:", dec.toString());
console.log("decrypted:", dec.toString(CryptoJS.enc.Hex));
var json = dec.toString(CryptoJS.enc.Utf8);
console.log("json:", json)
// parse the JSON string to get the object
var obj = JSON.parse(json);

控制台输出:

key:  5f1903f5f2cb32acb4c1dcae9e30d374 
iv:  bfdb765d1ca4734c5748ffb9883dd15c 
ciphertext:  02717027440040375f7e0dbea69e77783949d3c160529eef0b9d59a751a2a312fa137a5034f6f4c9f89a348ef3f96fce40c8afe0c8a20a2f7a2535417cca2dd2 
dec: 50d411522f2d08b34d68f847fb78e0cfabf1144f933d83839431732a473079d9b3ed843e120d9ad6a239 
decrypted: 50d411522f2d08b34d68f847fb78e0cfabf1144f933d83839431732a473079d9b3ed843e120d9ad6a239 

Error during decryption:  Error: "Malformed UTF-8 data"

0 个答案:

没有答案