I'm trying to decrypt in c#, using bouncycastle, the result of the following php code:
<?php
$plaintext = 'The quick brown fox jumps over the lazy dog';
$cipher = "AES-128-CTR";
$key = "F5UgsDQddWGdgjdd";
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt(
$plaintext,
$cipher,
$key,
0,
$iv
);
$ciphertext = base64_encode($iv.$ciphertext);
echo $ciphertext."\n";
?>
in php, the following code works:
<?php
$cipher = "AES-128-CTR";
$key = "F5UgsDQddWGdgjdd";
$ciphertext = base64_decode( $_POST['ciphertext'] );
$iv = substr($ciphertext, 0, 16);
$content = substr($ciphertext, 16);
$text = openssl_decrypt(
$content,
$cipher,
$key,
0,
$iv
);
echo $text."\n";
?>
However, when I do the following in C# the result is just gibberish.
public string Test(string cipherTextStr)
{
var cipherText = Convert.FromBase64String(cipherTextStr);
var iv = cipherText.Take(16).ToArray();
var content = cipherText.Skip(16).ToArray();
byte[] keyBytes = Encoding.UTF8.GetBytes("F5UgsDQddWGdgjdd");
IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");
cipher.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", keyBytes), iv));
byte[] decryptedBytes = cipher.DoFinal(content);
return Encoding.UTF8.GetString(decryptedBytes);
}
The same C# code works if I don't have to separate iv and content which makes me think that I'm either doing the initial FromBase64String wrong or the take and skip from the byte array.
CodePudding user response:
When you pass $option = 0
to openssl_encrypt
, the input data is PKCS#7 padded and the output data is base64 encoded. If you don't want any padding and base64 encoded output, use this option value:
$ciphertext = openssl_encrypt(
$plaintext,
$cipher,
$key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
$iv
);
Update: modify C#, manually decode the encrypted data.
content = Convert.FromBase64String(Encoding.UTF8.GetString(content));