我有一个密文,在3DES CBC模式下加密,我在解密它时遇到了一些麻烦。我有以下信息(不是实际值):
<?php
// Three 16 character long keys
$key1 = '1234567890123456';
$key2 = '6543210987654321';
$key3 = '6549873210456123';
// The initialisation vector
$ivec = '0102030405060708';
// A token which looks something like this
$token = '2ad82e09e3b4e7c491e4bb9fb7c606e1';
?>
我的解密功能基于this blog post中的PHP类。它看起来像这样:
<?php
function decrypt($key,$iv,$token) {
$td = mcrypt_module_open('tripledes', '', 'cbc', '');
$iv = substr($iv, 0, mcrypt_enc_get_iv_size($td));
$expected_key_size = mcrypt_enc_get_key_size($td);
$key = substr(md5($key), 0, $expected_key_size);
mcrypt_generic_init($td, $key, $iv);
$decrypted_string = trim(mdecrypt_generic($td, base64_decode($token)));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $decrypted_string;
}
?>
但是,我不确定如何将三个键输入算法。我试过将它们链接在一起如下:$ key1。$ key2。$ key3,并且顺序相反,但无济于事。
任何帮助都将不胜感激。
答案 0 :(得分:2)
//三个16个字符的长键$ expected_key_size是24,3 * 8。键很可能是十六进制格式。
function foo($hex) {
$rv = '';
foreach(str_split($hex, 2) as $b) {
$rv .= chr(hexdec($b));
}
return $rv;
}
// Three 16 character long keys
$key1 = '1234567890123456';
$key2 = '6543210987654321';
$key3 = '6549873210456123';
$key = foo($key1.$key2.$key3);
答案 1 :(得分:2)
我最终发现了这个功能的问题。它是将密钥,IVEC和令牌从Hex转换,删除解密密钥的MD5哈希并删除生成的纯文本的Base64解码的组合。
导致纯文本的填充字符有点奇怪,但是用rtrim()删除了。值得注意的是,加密最初是使用一些标准Java库在JSP中完成的,因此这对于其他任何来自Java加密→PHP解密的人来说都是有用的。
感谢您的帮助VolkerK,这是我最终使用的功能(包括我在下面未添加的十六进制功能):
$algorithm = 'tripledes';
$key = 'F123ACA...'; // Some hex key
$ivec = 'FE12FA1...'; // Some hex ivec
$token = 'F2ACE12...'; // Some hex token
$mode = 'cbc';
$key = foo($key);
$ivec = foo($ivec);
$token = foo($token);
function decrypt($key,$iv,$algorithm,$mode,$token) {
$td = mcrypt_module_open($algorithm, '', $mode, '') ;
$iv = substr($iv, 0, mcrypt_enc_get_iv_size($td));
$expected_key_size = mcrypt_enc_get_key_size($td);
$key = substr($key, 0, $expected_key_size);
mcrypt_generic_init($td, $key, $iv);
$response = rtrim(mdecrypt_generic($td, $token), '');
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $response;
}
$plaintext = decrypt($key,$ivec,$algorithm,$mode,$token);