我想实现一个PHP加密脚本到JavaScript中。我的PHP脚本返回一个128个字符的字符串,而我的基于Javascript的返回160个字符。基于JavaScript的版本的前128个字符与基于PHP的版本匹配。Javascript AES加密返回太多字符
function pkcs5_pad ($text, $blocksize){
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
$skey = "somekey";
$ivKey = "someIVKey";
$input = "empid=xxxxxx;timestamp=Sat, 19 Nov 2016 00:33:03 UTC";
try {
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,'cbc');
echo strlen($input) . "\n";
$input = pkcs5_pad($input, $size);
echo strlen($input) . "\n";
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
$key = pack('H*', $skey);
$iv = pack('H*', $ivKey);
# The key size used is 16, 24 or 32 bytes - for AES-128, 192 and 256 respectively
if (mcrypt_generic_init($cipher, $key, $iv) != -1){
$encrypted = mcrypt_generic($cipher, $input);
mcrypt_generic_deinit($cipher);
$encryptedString = bin2hex($encrypted);
}
echo $encryptedString . "\n";
echo strlen($encryptedString) . "\n";
} catch (Exception $ex) {
echo $ex->getMessage();
}
长度strlen($encryptedString)
这里给我128个字符。
我的JavaScript版本使用CryptoJS创建看起来像这样
var aesKey = "somekey";
var ivKey = "someIVKey";
function pkcs5_pad (text, blocksize){
console.log(text.length);
var pad = blocksize - (text.length % blocksize);
console.log("pad:" + pad);
return text + str_repeat(chr(pad), pad);
}
input = "empid=xxxxxx;timestamp=Sat, 19 Nov 2016 00:33:03 UTC";
var size = 16;
console.log(input.length);
var input = pkcs5_pad(input, size);
console.log('"' + input + '"');
console.log(input.length);
var key = CryptoJS.enc.Hex.parse(aesKey);
var iv = CryptoJS.enc.Hex.parse(aesIV);
var encryptedString = CryptoJS.AES.encrypt(input,key,{iv: iv});
console.log(encryptedString.ciphertext.toString().length);
encryptedString = encryptedString.ciphertext.toString();
匹配的一切,包括之前和之后pkcs5_pad串lenght。我正在使用locutus.io中的一些额外的JavaScript代码来调用str_repeat和chr。这里encryptedString.ciphertext.toString().length
返回160个字符,第一个128个匹配我的PHP脚本。
我的理解是,CryptoJS的第3版使用CBC模式,但我也明确将模式设置为CBC无济于事。我也返回加密的字符串为十六进制
encryptedString = encryptedString.ciphertext.toString(CryptoJS.enc.Hex);
我在哪里出错了?
编辑 的PHP版本的输出是
86b1c9874069129d0852eade01eb753a176a1c6155c4af3ac447ae0a5350b92c3447f95be9c4f8cdbf14503696bcaa16e6307c1605a2cac503239db9d1ac6fb3
的JavaScript版本的输出是
86b1c9874069129d0852eade01eb753a176a1c6155c4af3ac447ae0a5350b92c3447f95be9c4f8cdbf14503696bcaa16e6307c1605a2cac503239db9d1ac6fb33051208849788f8a90db1cbe2494cac7
什么输出是什么样子? – Sammitch
输出已添加到问题 – Robbert
最好不要使用mcrypt的,它已经现在放弃的近十年。因此它已被弃用,并将在PHP 7.2中从核心和PECL中删除。它不支持标准的PKCS#7(néePKCS#5)填充,只有非标准的null填充甚至不能用于二进制数据。 mcrypt有很多优秀的[bug](https://sourceforge.net/p/mcrypt/bugs/)可以追溯到2003年。相反,考虑使用[defuse](https://github.com/defuse/php-encryption)或者[RNCryptor](https://github.com/RNCryptor),他们提供了一个完整的解决方案,正在维护和正确。 – zaph