I am trying to port an encryption code written in C# to PHP. The code below uses Rijndael-128 encryption. The result given by PHP code is slightly different than the C# code. I am under constraint of not using Salt and Random IV and not altering C# code. After browsing through many of the answers on stackoverflow on this issue and making several changes to the code still the code is not producing correct result.
C# code (member function of a class)
public static string Encrypt(string plainText, string passPhrase)
{
byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
var password = new Rfc2898DeriveBytes(passPhrase, new byte[8], 10000);
byte [] keyBytes= password.GetBytes(keysize / 8); //256/8
var symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
var memoryStream = new MemoryStream();
var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
return Convert.ToBase64String(cipherTextBytes);
}
PHP code (member function of a class)
public function encrypt(){
$plainText="Same_input_as_above";
$plainText=mb_convert_encoding($plainText,'UTF-8');
$passPhrase=mb_convert_encoding($this->secret,'UTF-8');
$salt=str_pad("",8,"\0");
$key= hash_pbkdf2 ( 'sha1' , $passPhrase, $salt , 10000 ,self::KEYSIZE/8, true);
$initVector=mb_convert_encoding(self::INITVECTOR,'UTF-8');
$tempCipher= mcrypt_encrypt (MCRYPT_RIJNDAEL_128 , $key , $plainText , MCRYPT_MODE_CBC,$initVector);
return base64_encode($tempCipher);
}
C# Output
O/Fi4tfdS5APen6YAboRnr%2B2bSrHSG71OHhX7YZbbhJYr8mt3HxfYza4bjkV8gtq
PHP Output
O/Fi4tfdS5APen6YAboRnr%2B2bSrHSG71OHhX7YZbbhIpdOLx9oscZnlAdyTMgeGX
The decryption function of C# works fine with the cipher created by itself but gives Padding is invalid and cannot be removed. error while decoding PHP generated cipher.
Talk1:
It is best not to use mcrypt, it is abandonware, has not been updated in years and does not support standard PKCS#7 (née PKCS#5) padding, only non-standard null padding that can't even be used with binary data. mcrypt had many outstanding bugs dating back to 2003. Instead consider using defuse or RNCryptor, they provide a complete solution and are being maintained and is correct.
Talk2:
. thanks. First I thought it was the empty salt that was making trouble after applying null padded salt I forgot to uncomment the plain-text padding lines after.
Solutions1
The problem is that mcrypt only supports non-standard null padding. The C# library supports standard PKCS#7 (née PKCS#5) padding. See PKCS#7 padding.
You can easily add and remove PKCS#7 padding prior to encryption and after decryption, in PHP:
Add PKCS#7 padding
$padLength = $blockSize - (strlen($clearText) % $blockSize);
$clearText = $clearText . str_repeat(chr($padLength), $padLength);
Strip PKCS#7 padding
$padLength = ord($cryptText[strlen($cryptText)-1]);
$cryptText = substr($cryptText, 0, strlen($cryptText) - $padLength);
The better solution is not to use mcrypt. Options include defuse or RNCryptor which provide a complete solution.
Talk1:
thanks for suggesting better solutions, but while decrypting the removal of padding was not required