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!
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!