Edit #2
In all my excitement of having figured out why garbage was coming out when you actually get the decryption code working, I neglected to answer the question as to why you were getting the error:
Exception calling "TransformFinalBlock" with "3" argument(s): "The input data is not a complete block."
The issue is that you are passing in a chunk of data that is not long enough to be a block
. Using the original string that you were converting to bytes, you get an array of 24 bytes, but the block size is 16 bytes, so you would need to have an array with a length that is a multiple of 16. Using the correct string vt/4HDs0gCAy8D8b/m9F8g==
, you will get an array of 16, which will work (although there is a minor correction to your call to TransformFinalBlock
that needs to be made, you want to call it with an offset of 0 and with the length of your input array - I have updated my solution below to show this).
End Edit #2
I figured it out!!!!
So, first problem is here:
echo base64_encode($data);
The $data
value you are getting back from openssl_encrypt is already base64 encoded, so there is no need to encode it again. If you remove that line, you get this string back vt/4HDs0gCAy8D8b/m9F8g==
(see ideone link)
And just in case you need proof that that is what happened, here is another ideone link showing what happens if you convert your string from Base64 and then convert those bytes to a string, you get the original Base64 encoded string that came out of the call to openssl_encrypt.
Now for the decrypting part (note, I am going to post the code in C# but should be fairly trivial to convert to powershell, if there is an issue comment and I will try to help). I typically would create a decryptor and use a stream, but I wanted to fit with your code, so I am using the TransformBlock
method.
string result = null;
using (var aes = new AesManaged())
{
// openssl_encrypt will zero pad a key that is not the correct length
var key = Encoding.UTF8.GetBytes("CefaiNooH4oi6oje");
if (key.Length < 32)
{
var temp = new byte[key.Length + (32 - key.Length % 32)];
Array.Copy(key, temp, key.Length);
key = temp;
}
var iv = Encoding.UTF8.GetBytes("Choodub8ahd4choo");
aes.Mode = CipherMode.CBC;
aes.KeySize = 256;
aes.Key = key;
aes.IV = iv;
aes.Padding = PaddingMode.Zeros;
var cipher = Convert.FromBase64String("vt/4HDs0gCAy8D8b/m9F8g==");
using (var decryptor = aes.CreateDecryptor())
{
var buffer = decryptor.TransformFinalBlock(cipher, 0, cipher.Length);
result = Encoding.UTF8.GetString(buffer);
}
}
Edit
Adding decryption code using streams (how I normally do it in C#)
using (var aes = new AesManaged())
{
// See sample above for setup code, omitted for brevity
using (var dest = new MemoryStream())
using (var input = new MemoryStream(cipher))
using (var cs = new CryptoStream(input, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
var buffer = new byte[1024];
var read = cs.Read(buffer, 0, buffer.Length);
while(read > 0)
{
dest.Write(buffer, 0, read);
read = cs.Read(buffer, 0, buffer.Length);
}
dest.Flush();
result = Encoding.UTF8.GetString(dest.ToArray());
}
}