我试图用PHP 5.4.4复制以下CryptoJS 3.1.2代码:
var plaintext = 'test';
var key = CryptoJS.enc.Utf8.parse('9rIY8vV8DdOKx3m6JocjEaObhhYc2NfY');
var iv = CryptoJS.enc.Utf8.parse('r0dkbnVQhklNeUGA');
var encrypted = CryptoJS.AES.encrypt(plaintext, 'euhe68vjdr1aX4F091c7aCggSMBf0A7M', key,{iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});
我发现了几个问题处理这个问题,但没有一个在plaintext
和key
之间的encrypt()
中有额外的参数。
CryptoJS wiki根本没有提到这个参数。然而,它是有效的。我可以这样解密:
var decrypted = CryptoJS.AES.decrypt(encrypted, 'euhe68vjdr1aX4F091c7aCggSMBf0A7M', key, {iv: iv});
如果我在decrypt()
调用中省略'euhe68vjdr1aX4F091c7aCggSMBf0A7M'
,它将不起作用。所以这个参数确实有作用。但是什么?是哈希还是盐?
有人知道我如何用PHP复制这个特定的加密过程吗?
我不能以任何方式修改这个JS代码。该代码位于登录页面上,用于在将凭据发送到服务器之前对其进行加密。
我正在尝试使用PHP-cURL从命令行向该服务器提交凭据,这就是为什么我需要重现这个加密过程。
更新:感谢Jim的回答,我现在有了合适的JavaScript,现在我需要帮助在PHP中复制代码
JS:
var plaintext = 'test';
var key = 'euhe68vjdr1aX4F091c7aCggSMBf0A7M';
var iv = CryptoJS.enc.Utf8.parse('r0dkbnVQhklNeUGA');
var encrypted = CryptoJS.AES.encrypt(plaintext, key, key,{iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7})
encrypted
= U2FsdGVkX1+ZujoXKqDHcO+4N1QO+Nv1KHUMFjZos1s=
下面是解密:
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
decrypted
= test
我已经尝试了许多不同的方法来复制加密与PHP,但没有一个给出一个字符串,我可以解码与上面的JS。
例如,使用AES_Encryption类,我尝试了以下代码:$key = 'euhe68vjdr1aX4F091c7aCggSMBf0A7M';
$iv = 'r0dkbnVQhklNeUGA';
$message = 'test';
$AES = new AES_Encryption($key, $iv, PKCS7);
$encrypted = $AES->encrypt($message);
$decrypted = $AES->decrypt($encrypted);
$base64_encrypted = base64_encode('Salted__'.$encrypted);
我结束了U2FsdGVkX18eEv+TnigBEKGJL8t/V1Hm
而不是U2FsdGVkX1+ZujoXKqDHcO+4N1QO+Nv1KHUMFjZos1s=
请注意,这两个字符串以相同的方式开始,这要归功于我添加的'Salted__'前缀(因为CryptoJS似乎做同样的事情)。
如有任何提示,不胜感激。
**更新:FIXED **
这段PHP代码与上面的CryptoJS代码是完美匹配的。
function ssl_encrypt($pass, $data)
{
// Set a random salt
$salt = substr(md5(mt_rand(), true), 8);
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = $block - (strlen($data) % $block);
$data = $data . str_repeat(chr($pad), $pad);
// Setup encryption parameters
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, "", MCRYPT_MODE_CBC, "");
$key_len = mcrypt_enc_get_key_size($td);
$iv_len = mcrypt_enc_get_iv_size($td);
$total_len = $key_len + $iv_len;
$salted = '';
$dx = '';
// Salt the key and iv
while (strlen($salted) < $total_len) {
$dx = md5($dx.$pass.$salt, true);
$salted .= $dx;
}
$key = substr($salted,0,$key_len);
$iv = substr($salted,$key_len,$iv_len);
mcrypt_generic_init($td, $key, $iv);
$encrypted_data = mcrypt_generic($td, $data);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
//return chunk_split(base64_encode('Salted__' . $salt . $encrypted_data),32,"'r'n");
return base64_encode('Salted__' . $salt . $encrypted_data);
}
function ssl_decrypt($password, $edata)
{
$data = base64_decode($edata);
print "Data: " . $data . "'n";
$salt = substr($data, 8, 8);
print "Salt (Base64): " . base64_encode($salt) . "'n";
$ct = substr($data, 16);
print "Content (Base64): " . base64_encode($ct) . "'n";
$rounds = 3;
$data00 = $password.$salt;
print "Data00 (Base64): " . base64_encode($data00) . "'n";
$md5_hash = array();
$md5_hash[0] = md5($data00, true);
$result = $md5_hash[0];
print "MD5-Hash[0] (Base64): " . base64_encode($result) . "'n";
for ($i = 1; $i < $rounds; $i++) {
$md5_hash[$i] = md5($md5_hash[$i - 1].$data00, true);
$result .= $md5_hash[$i];
print "Result (Base64): " . base64_encode($result) . "'n";
}
$key = substr($result, 0, 32);
print "Key (Base64): " . base64_encode($key) . "'n";
$iv = substr($result, 32, 16);
print "IV (Base64): " . base64_encode($iv) . "'n";
print "Decrypted: " . openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv) . "'n";
}
$encryptedString = ssl_encrypt('euhe68vjdr1aX4F091c7aCggSMBf0A7M', 'test');
$decryptedString = ssl_decrypt('euhe68vjdr1aX4F091c7aCggSMBf0A7M', $encryptedString);
我记不起在哪里找到的。对不起。
这是JavaScript的事情,而不是CryptoJS的事情。试试这个:
var decrypted = CryptoJS.AES.decrypt(encrypted, 'euhe68vjdr1aX4F091c7aCggSMBf0A7M', {iv: iv});
或:
key = 'euhe68vjdr1aX4F091c7aCggSMBf0A7M';
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {iv: iv});
你会发现你认为是关键的东西,其实根本不是关键。它与末尾的可选参数分组,并且丢失了。
'euhe68vjdr1aX4F091c7aCggSMBf0A7M'是您的密钥,或者是您的密钥的派生。