tags:

views:

1038

answers:

2

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.

+2  A: 

// 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);
VolkerK
+2  A: 

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