Reputation: 576
The issue is why does a 32 character string work in C# .NET but not in php mcrypt, and how to make them compatible? (I have a method of doing it with AES, 3DES remains open.
I'm trying to create a cryptography api which uses Microsofts Crypto Api's in .NET and PHP's mcrypt to encrypt and decrypt data.
C# should be able to encrypt and decrypt, the PhP only needs to decrypt. The problem is I would like the user to be able to define their own key. To do this, I have md5 hashed the password they enter. This works perfectly on the C # side, but in PHP I get
Warning: mcrypt_decrypt() [function.mcrypt-decrypt]: Size of key is too large for this algorithm in C:\xampp\htdocs\failcrypt\crypt.php on line 40
(An empty "" string should work, as well as fairly large keys.
All the links I can find have preset keys, but mine must work for arbitrary key sizes on both sides.
echo $key."</br>";
echo md5($key)."</br>";
$newKey = md5($key)."</br>";
echo strlen($newKey)."</br>";
$decrypted = mcrypt_decrypt(MCRYPT_3DES, md5($key), base64_decode($msg), MCRYPT_MODE_ECB);
echo $decrypted;
outputs
red (the key)
bda9643ac6601722a28f238714274da4 (the hash)
Upvotes: 2
Views: 2671
Reputation: 10171
The way you do it, the key size will never be arbitrary. It will always be the output of the MD5 hash. You are using a (weak) form of password based key derivation function (PBKDF). So the key really isn't the string "red", it is the output of the MD5 function.
$ echo red | tr -d [:space:] | openssl dgst
(stdin)= bda9643ac6601722a28f238714274da4
$ echo The quick brown fox jumps over the lazy dog. | tr -d [:space:] | openssl dgst
(stdin)= 09ecfef50e54940a3d241a10b7e70e3c
That being said, mcrypt_decrypt needs raw bytes for the key. Here is working code :
$key = "Use any string you want as a password.";
$encrypted = base64_decode("OcSlUzWMgac5RxYyt+An0g=="); //This is the base64 encoded cipher text
$newKey = hash("md5", $key, TRUE);
//echo base64_encode($newKey)."\n";
$decrypted = mcrypt_decrypt(MCRYPT_3DES, $newKey, $encrypted, MCRYPT_MODE_ECB);
echo $decrypted;
You can increase the strength of your PBKDF by adding salt and iterating many times. So instead of using only :
md5(password)
Use something like
md5(salt+md5(salt+md5(salt+md5(salt+md5(salt+password)))))
You get the idea. Better yet, use a PBKDF2 implementation in C# and PHP that produce the same key.
Upvotes: 2