...

View Full Version : mcrypt, 3des, 32 byte keys and oh dear god my brain



hinch
11-11-2010, 04:32 PM
I'm trying (in vein at the moment) to convert a c# encryption function to php!

Its a simple 3DES setup to encrypt a string that is passed along a query string to a c# application.

Now the c# code is as follows



public string SSOCFEncrypt(string inputValue)
{
string sKey = "g4h5cjdf57hjjdpjo41xd6awe7qwxvxz";

//re-seed the key with todays date
string strToday = DateTime.UtcNow.DayOfYear.ToString();

if (strToday.Length > 0)
sKey = strToday + sKey.Substring(strToday.Length);

//Set the Encryption Key
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.Key = Convert.FromBase64String(sKey);
/*the mode is the block cipher mode which is basically the
details of how the encryption will work. Here we use Electronic Codebook cipher
which means that a given bit of text is always encrypted
exactly the same when the same password is used.*/
des.Mode = CipherMode.ECB;

ICryptoTransform desdencrypt = des.CreateEncryptor();
/* the mode is the block cipher mode which is basically the
details of how the encryption will work. Here we use Electronic Codebook cipher
which means that a given bit of text is always encrypted
exactly the same when the same password is used.*/

Byte[] buff = ASCIIEncoding.ASCII.GetBytes(inputValue);
/* encrypt the byte buffer representation of the original string
and base64 encode the encrypted string. the reason the encrypted
bytes are being base64 encoded as a string is the encryption will
have created some weird characters in there. Base64 encoding
provides a platform independent view of the encrypted string
and can be sent as a plain text string to wherever.*/

return Convert.ToBase64String(desdencrypt.TransformFinalBlock(buff, 0, buff.Length));
}



pretty straight forward!

now my attempt in php to replicate its encryption routines allowing php to use this web service not just c# and cf



function desencrypt($input) {
//pad out input
// get the amount of bytes to pad
$extra = 8 - (strlen($input) % 8);
// add the zero padding
if($extra > 0) {
for($i = 0; $i < $extra; $i++) {
$input .= "\0";
}
}


$ssokey = 'g4h5cjdf57hjjdpjo41xd6awe7qwxvxz';
$todaysdate = date("z")+1;
if (strlen($todaysdate)>0) {
$newkey = $todaysdate.substr($ssokey,strlen($todaysdate),strlen($ssokey));
}
$key = base64_decode($newkey);

$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
//$ks = mcrypt_enc_get_key_size($td);
//$key = substr($newkey, 0, $ks);
/* Intialize encryption */
mcrypt_generic_init($td, $key, $iv);
/* Encrypt data */
$encrypted = mcrypt_generic($td, $input);
//echo mcrypt_get_key_size('tripledes', 'ecb');
/* Terminate encryption handler */
mcrypt_generic_deinit($td);
/* close module */
mcrypt_module_close($td);


/* Show string */
echo "<textarea>".base64_encode($encrypted)."</textarea>";
return base64_encode(trim($encrypted));

}


however best will in the world its simply wrong :)

for example the word cyclone encrypted with c# is BENLMFQ1kcE= but in php its coming out as F15/e+305FE= to confuse matters even more check this out

C#
k3beJouw6thohkA3+8Z9dGvLVdLmuc6Yvr2ApcT1rgU=
PHP
k3beJouw6thohkA3+8Z9dGvLVdLmuc6YhG4ti8GTeY8=

string encrypted
dave@angel-computers.co.uk

encrypted string is identical apart from last 10 or so chars! so very random!

I'm fairly sure that its to do with php not supporting 32 byte keys for mcrypt so it shortens the used key down BUT I have no way of testing this as obviously the base 64 decrypted key is a binary string ie: no display on the monitor magic.

I've knocked up a small c# encryption app for anyone brave enough to attempt this to check your php vs c# results www.angel-computers.co.uk/davestester.rar simply run setup.exe and it should appear in your start menu as daves SSO Tester, uninstall via admin panel (full c# code available on request if you wanna check its not a dodgy program)

This is now officially driving me insane I can't find a reason for it apart from the potential key length but still i'm not 100% sure that is the cause!

Afro_Programmer
11-11-2010, 05:35 PM
google (http://tinyurl.com/3xt8kpo)

Sorry, I just love using lmgtfy =D

hinch
11-11-2010, 06:35 PM
apart from google is useless for this :)
I've already been through about 40 different google search terms to try and work out the issue. Actually found alot of threads with people having same issue as me but none of them have had answers in them :)

slappyjaw
11-12-2010, 09:44 PM
This is probably a stupid question and i dont know c# that well but is the time and date the same in both? Because for today the php will give out 315 plus 1 like in your script.

hinch
11-19-2010, 09:44 AM
This is probably a stupid question and i dont know c# that well but is the time and date the same in both? Because for today the php will give out 315 plus 1 like in your script.


slightly different php counts from zero c# from 1 thats why i've got the+1 on the php

on the upside I've got this 99% working now.

it works for some users but not for others.

for example

dave@angel-computers.co.uk encrypts fine

stephendenny@sky.com encrypts wrong
pb/OfKGXTX1ZqDR1QP6dlqdJB9pHAno= <===php
pb/OfKGXTX1ZqDR1QP6dlqdJB9pHAnoK <===c#

last character is wrong I assumed it was down to a space at the end but i've trimmed like the devil and can't work it out

Riceburner
05-25-2011, 03:35 PM
I've got a similar issue - a string encoded with TripleDES on an ASP server, I'm trying to decode it in php, but the supplied key is a 16character string, that for some reason they've told me has to be hex encoded before use first - making it a 32 character string - too long for TripleDES!

Did you find a full solution to this problem?

Inigoesdr
05-25-2011, 05:35 PM
Hinch posted a followup thread here (http://www.codingforums.com/showthread.php?t=227666) with some code that might help.

Riceburner
05-26-2011, 09:40 AM
Hinch posted a followup thread here (http://www.codingforums.com/showthread.php?t=227666) with some code that might help.

Thanks - unfortunately it doesn't really help, I have no control whatsoever over the encrypting process, I'm dealing with a pre-encrypted string that I am trying to decrypt.

flakjacket
08-09-2011, 12:26 AM
I'm having a similar issue as well, again going between C# and PHP5. I even have the freedom to modify both server and client code, to no avail. I am starting to feel like the two are simply not compatible.

To test my theory, I built a test application. I have a routine that randomly generates keys and another one that generates 240,000 unique pieces of sample data patterned after my data - email addresses and DateTime strings. I send the encoded data and the key to the server for decoding and then compare the decoded result to the data. The server also mirrors the encoded data back to me so I can compare it to what was sent to make sure that the data didn't get corrupted somewhere - which it never has.

RESULT: Abject failure. I have tried different key lengths (8 bit, 16 bit, 24 bit) all to no avail. I have tried CBC, ECB ciphers, PKCS7 and Zero padding as well as numerous other little tweaks I've googled and nothing works. I can get both .NET and mcrypt to decode their own encrypted data with 100% success, but when trying to decode each others, both fail anywhere from a tantalizingly low 1% of the time to an alarming 50% of the time, depending on the key.

Unless someone can show me that I'm wrong - and by all means I hope someone can - I am ready to declare mcrypt and .NET incompatible and wash my hands of the endeavor to use them together.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum