Php和cryptoJS IV

时间:2016-03-09 18:47:40

标签: javascript php encryption cryptojs

我使用PHP加密和解密数据,如下所示:

$default

我现在希望能够使用Crypto-JS在本地加密我的数据(与PHP方法完全相同)。我已经完成了与上面相同的操作来获得密钥和iv:

<?php 
function encrypt($data, $secret){
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    return base64_encode($iv.openssl_encrypt($data, 'aes-256-cbc', $secret, 0, $iv));
}

function decrypt($encryptedData, $secret){
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $data = base64_decode($encryptedData);
    $iv = substr($data, 0, $iv_size);
    return openssl_decrypt(substr($data, $iv_size), 'aes-256-cbc', $secret, 0, $iv);
}
?>

现在使用Crypto-JS时,我尝试使用以下方法进行加密:

var key = '<?php echo $secret;?>';
var iv = '<?php echo base64_encode(mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND));?>';

但我还需要像使用PHP一样存储IV所以我添加了:

var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(text), CryptoJS.enc.Hex.parse(key), { iv: CryptoJS.enc.Hex.parse(iv) });

但是没有编码。所以我补充道:

var withIV = iv+encrypted;

但由于某种原因,这与上面的PHP编码不一样?

2 个答案:

答案 0 :(得分:0)

以下是我使用CryptoJS加密数据的方法:

function encrypt(str, key, iv) {
    var key = CryptoJS.enc.Hex.parse(key);
    var iv = CryptoJS.enc.Hex.parse(iv);
    return CryptoJS.AES.encrypt(str, key, { iv: iv }).toString();
};

在PHP中,我使用以下代码行解密该函数生成的加密字符串:

openssl_decrypt($encrypted_data_string, "AES-128-CBC", hex2bin($key_hex_string), 0, hex2bin($iv_hex_string));

我想如果你愿意的话,你可以用base 64编码/解码加密数据,而不是十六进制。无论如何,希望这有帮助!

答案 1 :(得分:0)

似乎你在连接CryptoJS中的IV和密文时遇到了麻烦。这很容易,因为CryptoJS的本机二进制数据格式(WordArray)支持concat函数:

var ivWords = CryptoJS.enc.Hex.parse(iv); // WordArray instance
var plaintext = CryptoJS.enc.Utf8.parse(text); // WordArray instance
var keyWords = CryptoJS.enc.Hex.parse(key); // WordArray instance
var encrypted = CryptoJS.AES.encrypt(plaintext, keyWords, { iv: ivWords }); // CipherParams instance

var ct = ivWords.clone().concat(encrypted.ciphertext); // WordArray instance
var ct = ct.toString(CryptoJS.enc.Base64); // string instance
console.log(ct);

// example data
var iv = "0102030405060708090a0b0c0d0e0f";
var text = "text";
var key = "1112131415161718191a1b1c1d1e1f";

// actual code
var ivWords = CryptoJS.enc.Hex.parse(iv); // WordArray instance
var plaintext = CryptoJS.enc.Utf8.parse(text); // WordArray instance
var keyWords = CryptoJS.enc.Hex.parse(key); // WordArray instance
var encrypted = CryptoJS.AES.encrypt(plaintext, keyWords, { iv: ivWords }); // CipherParams instance

var ct = ivWords.clone().concat(encrypted.ciphertext); // WordArray instance
var ct = ct.toString(CryptoJS.enc.Base64); // string instance
output.innerHTML = ct;
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/components/enc-base64-min.js"></script>
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
<div id="output"></div>

这将产生与

相同的输出
base64_encode($iv.openssl_encrypt($data, 'aes-256-cbc', $secret, 0, $iv));

只要iv实际上是十六进制编码的字符串,其中包含与$iv中的解码版本相同的字节。对于text(编码除外),key$data$secret,情况必须相同。