日期:2014-05-16  浏览次数:20497 次

AES加密 PHP 与 Javascript 加密内容为中文时不一致
首先是 Javascript 端
https://code.google.com/p/crypto-js/

<script src="aes.js"></script>
<script src="pad-zeropadding.js"></script>
<script
<script>
function Encrypt(data,key,iv)
{
key  = CryptoJS.enc.Latin1.parse(key);
iv   = CryptoJS.enc.Latin1.parse(iv);
return CryptoJS.AES.encrypt(data,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.ZeroPadding}).toString();
}
function Decrypted(data,key,iv)
{
try
{
key  = CryptoJS.enc.Latin1.parse(key);
iv   = CryptoJS.enc.Latin1.parse(iv);
return CryptoJS.enc.Utf8.stringify(CryptoJS.AES.decrypt(data,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.ZeroPadding})).toString();
}catch(err)
{
return ""+err;
}
}
var bb = Encrypt(CryptoJS.enc.Utf8.parse("Test你好String"),"1234567812345678","1234567812345678");
document.write(bb+"<br />");
document.write(Decrypted(bb,"1234567812345678","1234567812345678"));
</script>

这里是PHP端
<?php
class Encryption
{
public function Encrypted($data,$privateKey,$iv)
{
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_CBC, $iv));
}
public function Decrypted($data,$privateKey,$iv)
{
   return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $privateKey, base64_decode($data), MCRYPT_MODE_CBC, $iv);
}
}
$ab = new Encryption();
$kk= $ab->Encrypted("Test你好String","1234567812345678","1234567812345678");
echo $kk.'<br />';
echo $ab->Decrypted($kk,"1234567812345678","1234567812345678");
?>

PHP输出:
gh5JcIUgz69fl8YFdoiyvg==
Test你好String

Javascript输出:
LU1E3DHT641V8X3k42Tx/w==
Test你好String


我用JSP也做了一份,结果是与PHP一致的,javascript如何解决?
------解决方案--------------------
这是中文字符集引起的,与算法本身无关!

在浏览器中,中文字符都被转换成了 unicode 编码(UCS-2)
这一点你可这样观察到
s = '你好';
document.write(s.charCodeAt(0)+','+s.charCodeAt(1));
输出:20320,22909
print_r(unpack('n*', iconv('gbk', 'ucs-2', '你好')));
输出:Array
(
    [1] => 20320
    [2] => 22909
)

明文不同,自然密文也就不同了