我使用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."
这里可能有什么问题?
答案 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);
}
}