我有一个用Perl Crypt :: CBC(Rijndael,cbc)加密的加密字符串。原始明文用Crypt :: CBC的encrypt_hex()方法加密。
$encrypted_string = '52616e646f6d49567b2c89810ceddbe8d182c23ba5f6562a418e318b803a370ea25a6a8cbfe82bc6362f790821dce8441a790a7d25d3d9ea29f86e6685d0796d';
我使用了32个字符的密钥。
mcrypt成功编译成PHP,但我很难在PHP中解密字符串。我一直在胡言乱语。
如果我解包('H *',$ encrypted_string),我会看到'RandomIV'后面跟着二进制文件。
我似乎无法正确提取IV并分离实际的加密消息。我知道我没有提供我的信息,但我不确定从哪里开始。
$cipher = 'rijndael-256';
$cipher_mode = 'cbc';
$td = mcrypt_module_open($cipher, '', $cipher_mode, '');
$key = '32 characters'; // Does this need to converted to something else before being passed?
$iv = ?? // Not sure how to extract this from $encrypted_string.
$token = ?? // Should be a sub-string of $encrypted_string, correct?
mcrypt_generic_init($td, $key, $iv);
$clear = rtrim(mdecrypt_generic($td, $token), '');
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
echo $clear;
任何帮助,正确方向的指示,将不胜感激。如果我需要提供更多信息,请告诉我。
答案 0 :(得分:2)
我认为使用的IV只是由CBC :: Crypt随机生成的。如果我是正确的并且正确地阅读文档,那么它是解压缩字符串的32个第一个字节。
使用好的密钥尝试:
$cipher = 'rijndael-256';
$cipher_mode = 'cbc';
$td = mcrypt_module_open($cipher, '', $cipher_mode, '');
$key = '32 characters'; // Does this need to converted to something else before being passed?
$unpacked = pack('H*', '52616e646f6d49567b2c89810ceddbe8d182c23ba5f6562a418e318b803a370ea25a6a8cbfe82bc6362f790821dce8441a790a7d25d3d9ea29f86e6685d0796d');
$iv = substr($unpacked, 0, 32);
$token = substr($unpacked, 32);
mcrypt_generic_init($td, $key, $iv);
$clear = rtrim(mdecrypt_generic($td, $token), '');
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
echo $clear;
答案 1 :(得分:1)
这个答案是针对Crypt :: CBC的盐渍模式,而不是randomIV模式,但这是我在搜索解决方案时最终会遇到的页面,而其他人也可能。
使用此perl代码时:
my $cipher = Crypt::CBC->new(
-key => $password,
-cipher => 'Rijndael',
-salt => 1,
-header => 'salt',
) || die "Couldn't create CBC object";
$string = $cipher->encrypt_hex($input);
(或者甚至没有默认具有这些值的salt和header) Perl将创建一个符合OpenSSL标准的哈希。 我没有找到任何知道如何读取它的PHP方法,所以这里是我在CBC.pm中找到的解码的PHP版本。 我提取密钥和iv,然后我让mcrypt完成这项工作。
function cred_decrypt($input, $password)
{
/************************* Inspired by Crypt/CBC.pm *******************************/
$input = pack('H*', $input);
if (substr($input, 0, 8) != 'Salted__') {
die("Invalid hash header, expected 'Salted__', found '".substr($input, 0, 8)."'");
}
$salt = substr($input, 8, 8);
$input = substr($input, 16);
$key_len = 32;
$iv_len = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$data = '';
$d = '';
while (strlen($data) < $key_len+$iv_len) {
$d = md5($d . $password . $salt, TRUE);
$data .= $d;
}
$key = substr($data, 0, $key_len);
$iv = substr($data, $key_len, $iv_len);
/**********************************************************************************/
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $input, MCRYPT_MODE_CBC, $iv), "\0\n\3");
}
注意:在我的情况下需要rtrim,如果有的话可能会吃掉新行。
答案 2 :(得分:0)
这也不起作用。我有一种感觉,Perl的CBC :: Crypt与PHP的mcrypt功能有很大的不同。我一直在尝试在我的PHP目录中找到mcrypt函数的源代码来比较它们,但还没有运气。