使用 MCrypt 解密密文(3DES CBC 模式)

发布于 2024-07-29 04:19:32 字数 1156 浏览 7 评论 0原文

我有一个以 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';
?>

我的解密函数基于 这篇博文。 它看起来像这样:

<?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,并以相反的顺序,但无济于事。

任何帮助,将不胜感激。

I have a ciphertext, encrypted in 3DES CBC mode, and I'm having some trouble decrypting it. I have the following information (not actual values):

<?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';
?>

I based my decryption function off the PHP Class that is found in this blog post. It looks like this:

<?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;
}
?>

However, I'm not sure how to feed the three keys into the algorithm. I have tried chaining them together like so: $key1.$key2.$key3, and in reverse order, but to no avail.

Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

她比我温柔 2024-08-05 04:19:32

// 三个 16 个字符长的键

$expected_key_size is 24, 3*8. The keys are most likely in hex format.

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);

// Three 16 character long keys

$expected_key_size is 24, 3*8. The keys are most likely in hex format.

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);
少年亿悲伤 2024-08-05 04:19:32

最后发现是函数的问题。 它是从十六进制转换密钥、IVEC 和令牌、删除解密密钥的 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);

I found the problem with the function in the end. It was a combination of converting the key, IVEC and token from Hex, removing the MD5 hash of the decryption key and removing the Base64 decoding of the resulting plain text.

The padding character that resulted in the plain text was a bit odd, but that's stripped away with rtrim(). It may also be worth noting that the encryption was initially done in JSP using some standard Java libraries, so this might be useful for anyone else going from Java Encryption → PHP Decryption.

Thanks for your help VolkerK, here's the function I ended up using (including your hex function which I haven't added below):

$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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文