我一直在我的 iOS 应用程序中使用RNCryptor。由于应用程序的一些问题,我需要解密一些运行 PHP 5.4 的数据服务器端。RNCryptor 包包含 PHP 代码,但它仅适用于 RNCryptor 的 2.x 分支。我的数据是用 1.x 分支加密的。不幸的是,RNCryptor 2.x 不向后兼容 1.x。
据我所知,这些分支之间的唯一区别是 1.x 使用 AES CTR 模式来加密文本,而 2.x 现在使用 AES CBC。但我不知道如何调整 PHP 代码以使用 CTR。我也不确定 1.x 和 2.x 之间是否还有其他变化。我发现关于 1.x 的有用信息非常少。
这是用于从 2.x 行解密数据的 RNCryptor 代码:
/**
* @param string $b64_data Data encrypted by RNCryptor 2.x
* @return string|false Decrypted plaintext string, or false if decryption fails
*/
function decrypt_data($b64_data) {
global $gPassword; // the password string that was used to encrypt the data
// kRNCryptorAES256Settings
$algorithm = MCRYPT_RIJNDAEL_128;
$key_size = 32;
$mode = MCRYPT_MODE_CBC;
$pbkdf2_iterations = 10000;
$pbkdf2_prf = 'sha1';
$hmac_algorithm = 'sha256';
// back to binary
$bin_data = base64_decode($b64_data);
// extract salt
$salt = substr($bin_data, 2, 8);
// extract HMAC salt
$hmac_salt = substr($bin_data, 10, 8);
// extract IV
$iv = substr($bin_data, 18, 16);
// extract data
$data = substr($bin_data, 34, strlen($bin_data) - 34 - 32);
$dataWithoutHMAC = chr(2).chr(1).$salt.$hmac_salt.$iv.$data;
// extract HMAC
$hmac = substr($bin_data, strlen($bin_data) - 32);
// make HMAC key
$hmac_key = hash_pbkdf2($pbkdf2_prf, $gPassword, $hmac_salt, $pbkdf2_iterations, $key_size, true);
// make HMAC hash
$hmac_hash = hash_hmac($hmac_algorithm, $dataWithoutHMAC , $hmac_key, true);
// check if HMAC hash matches HMAC
if($hmac_hash != $hmac) {
echo "HMAC mismatch".$nl.$nl.$nl;
return false;
}
// make data key
$key = hash_pbkdf2($pbkdf2_prf, $gPassword, $salt, $pbkdf2_iterations, $key_size, true);
// decrypt
$cypher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
// initialize encryption handle
if (mcrypt_generic_init($cypher, $key, $iv) != -1) {
// decrypt
$decrypted = mdecrypt_generic($cypher, $data);
// http://www.php.net/manual/en/function.mdecrypt-generic.php
// We found that sometimes the resulting padding is not null characters "\0" but rather one of several control characters.
// If you know your data is not supposed to have any trailing control characters "as we did" you can strip them like so.
$decrypted = preg_replace( "/\p{Cc}*$/u", "", $decrypted );
// clean up
mcrypt_generic_deinit($cypher);
mcrypt_module_close($cypher);
return trim($decrypted);
}
return false;
}
我真的需要一个像上面这样的函数,它可以处理由 RNCryptor 的 1.x 行加密的数据。除此之外,有人知道我如何自己调整上述功能吗?谢谢!