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)
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.
精彩评论