为什么加密,然后解密给我一个不同的输出?

时间:2014-06-16 16:47:46

标签: php jquery encryption cryptojs

在我的代码中,我加密了一些数据两次。首先在jQuery中:

var text = '' + CryptoJS.Rabbit.encrypt("12345", "PassPhrase");

然后用ajax发布到php并再次加密:

function mc_encrypt($encrypt, $key){
    $encrypt = serialize($encrypt);
    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
    $key = pack('H*', $key);
    $mac = hash_hmac('sha256', $encrypt, substr(bin2hex($key), -32));
    $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt.$mac, MCRYPT_MODE_CBC, $iv);
    $encoded = base64_encode($passcrypt).'|'.base64_encode($iv);
    return $encoded;
}

然后,它存储在数据库中。如果用户想要再次访问该值,我将从数据库中检索它,然后解密它:

function mc_decrypt($decrypt, $key){
    $decrypt = explode('|', $decrypt);
    $decoded = base64_decode($decrypt[0]);
    $iv = base64_decode($decrypt[1]);
    $key = pack('H*', $key);
    $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
    $mac = substr($decrypted, -64);
    $decrypted = substr($decrypted, 0, -64);
    $calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
    if($calcmac!==$mac){ return false; }
    $decrypted = unserialize($decrypted);
    return $decrypted;
}

然后将其发回jQuery并再次解密:

var text = CryptoJS.Rabbit.decrypt(text, "PassPhrase");
text = text.toString();
console.log(text);

但是,控制台中记录的值与开头的值('12345')完全不同。我不知道为什么会这样,过去两天我一直在看这个问题,但我似乎无法弄清楚问题......

1 个答案:

答案 0 :(得分:0)

CryptoJS.Rabbit.decrypt正在返回字数组,您正在调用 toString 。对于“12345”,我猜你看到的结果是“3132333435”。

使用CryptoJS stringify ,例如CryptoJS.enc.Utf16.stringify(text)或CryptoJS.enc.Utf8.stringify(text),具体取决于原始编码。

您可以通过修改代码来选择进入时的编码,例如:

p = CryptoJS.enc.Utf8.parse("12345");
text = '' + CryptoJS.Rabbit.encrypt(p, "PassPhrase");

然后回程:

var text = CryptoJS.Rabbit.decrypt(text, "PassPhrase");
text = CryptoJS.enc.Utf8.stringify(text); // use same encoding as original input
console.log(text);