无法解密AES加密字符串

时间:2017-12-16 07:02:54

标签: php powershell encryption aes

我使用openssl_encrypt加密字符串并在powershell中解密它们

在PHP中

   $data = "helloWorld";

   $key  = 'CefaiNooH4oi6oje';
   $iv   = 'Choodub8ahd4choo';
   $data = openssl_encrypt($data, 'AES-256-CBC', $key, 0, $iv);

   echo base64_encode($data);

在Powershell中

$data = "dnQvNEhEczBnQ0F5OEQ4Yi9tOUY4Zz09"
$data = [System.Convert]::FromBase64String($data)

$aesManaged = New-Object "System.Security.Cryptography.AesManaged"
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
$aesManaged.Key = [system.Text.Encoding]::UTF8.GetBytes("CefaiNooH4oi6oje")
$aesManaged.IV = [system.Text.Encoding]::UTF8.GetBytes("Choodub8ahd4choo")
$decryptor = $aesManaged.CreateDecryptor();

$clear = $decryptor.TransformFinalBlock($data, 16, $data.Length - 16);

[System.Text.Encoding]::UTF8.GetString($clear).Trim([char]0)

然后我收到了一个错误:

Exception calling "TransformFinalBlock" with "3" argument(s): "The input data is not a complete block."

这里可能有什么问题?

1 个答案:

答案 0 :(得分:1)

编辑#2
在我实际获得解密代码工作时弄清楚为什么垃圾出现的所有兴奋时,我忽略了回答为什么你得到错误的问题:
Exception calling "TransformFinalBlock" with "3" argument(s): "The input data is not a complete block."
问题是您传递的数据块不够长,不足以成为block。使用您要转换为字节的原始字符串,您将获得一个24字节的数组,但块大小为16字节,因此您需要一个长度为16的倍数的数组。使用正确的字符串{ {1}},你将获得一个16的数组,这将是有效的(虽然你需要进行的vt/4HDs0gCAy8D8b/m9F8g==调用有一个小的修正,你想调用它的偏移量为0和输入数组的长度 - 我已经更新了我的解决方案以显示此信息。)

结束编辑#2

我想通了!!!!

所以,第一个问题在这里:

TransformFinalBlock

您从openssl_encrypt返回的echo base64_encode($data); 值已经是base64编码的,因此无需再次对其进行编码。如果删除该行,则会返回此字符串$data(请参阅ideone链接)

如果你需要证明发生了什么,这里有另一个ideone链接,显示如果从Base64转换字符串然后将这些字节转换为字符串会发生什么,你得到原始的Base64编码来自openssl_encrypt调用的字符串。

现在对于解密部分(注意,我将在C#中发布代码但是转换为PowerShell应该相当简单,如果有问题评论,我会尽力帮助)。我通常会创建一个解密器并使用流,但我想要适合您的代码,所以我使用的是vt/4HDs0gCAy8D8b/m9F8g==方法。

TransformBlock

修改 使用流添加解密代码(我通常如何在C#中执行)

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);
    }
}