I have a PHP application using openSSL to send a AES-256-CBC encrypted string with Base64 encoding to a .NET application. I start the decrypt method, but I always error when I try to actually decrypt the data. The error states "Padding is invalid and cannot be removed". What am I doing wrong here?
The encrypted Base64 value generated by the PHP function is: p07cNwcvcYLxvYHCUsmZqKYr40IXXYjEHr7r+JdgXiJT5/wpDSDmr48JLOXyNEL7
The key is: M2AZULUALPHA
The salt is: TripBuilder2017x
The PHP function is:
function encrypt($text) {
$key = "M2AZULUALPHA";
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$padding = $block - (strlen($text) % $block);
$text .= str_repeat(chr($padding), $padding);
$crypttext = openssl_encrypt($text,'aes-256-cbc', $key, OPENSSL_RAW_DATA, 'TripBuilder2017x');
return base64_encode($crypttext);
}
The .NET Decrypt function:
private string Decrypt(string cipherText)
{
string EncryptionKey = "M2AZULUALPHA";
byte[] saltArray = Encoding.ASCII.GetBytes("TripBuilder2017x");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, saltArray);
encryptor.Mode = CipherMode.CBC;
encryptor.BlockSize = 128;
encryptor.KeySize = 256;
encryptor.Padding = PaddingMode.PKCS7;
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
UPDATE I went to an online openSSL decrypt tool, entered my IV,Key and base64 text. It generated the correct string but had some weird blocks in the string.
UPDATE 2 Here is the updated PHP code. I increased the key size to 16 bytes as well. I am still receiving the same error.
$key = "M2AZULUALPHAECHO";
$salt = "TripBuilder2017x";
$mode = "aes-256-cbc";
$text = "BrassMonkey";
function encrypt($text,$key,$salt,$mode) {
return base64_encode(encryptplain($text,$key,$salt,$mode));
}
function encryptplain($text,$key,$salt,$mode) {
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$padding = $block - (strlen($text) % $block);
$text .= str_repeat(chr($padding), $padding);
$crypttext = openssl_encrypt($text, $mode, $key, 1, $salt);
return ($crypttext);
}
UPDATE 3: My .NET Code
private string Decrypt(string cipherText)
{
string EncryptionKey = "M2AZULUALPHAECHO";
byte[] saltArray = Encoding.ASCII.GetBytes("TripBuilder2017x");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
encryptor.Mode = CipherMode.CBC;
encryptor.BlockSize = 128;
encryptor.KeySize = 256;
encryptor.Padding = PaddingMode.PKCS7;
encryptor.Key = Encoding.ASCII.GetBytes(EncryptionKey);
encryptor.IV = saltArray;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}