我需要解密来自在线服务的图片(这不是我的,所以我必须使用这种加密方式)。
此图片使用 AES / ECB 使用单个同步密钥加密,并使用 PKCS5 进行填充。
我尝试了几种方法来实现这一目标,但它们都没有奏效。我使用BoucyCastle加密库。
这是我的解密代码:
public static byte[] Decrypt(string input)
{
var cipher = CipherUtilities.GetCipher("AES/ECB/PKCS5Padding");
cipher.Init(false, new KeyParameter(Encoding.UTF8.GetBytes(KEY)));
byte[] todo = Encoding.UTF8.GetBytes(Pad(input));
byte[] bytes = cipher.ProcessBytes(todo);
byte[] final = cipher.DoFinal();
// Write the decrypt bytes & final to memory...
var decryptedStream = new MemoryStream(bytes.Length);
decryptedStream.Write(bytes, 0, bytes.Length);
decryptedStream.Write(final, 0, final.Length);
decryptedStream.Flush();
var decryptedData = new byte[decryptedStream.Length];
decryptedStream.Read(decryptedData, 0, (int)decryptedStream.Length);
return decryptedData;
}
private static string Pad(string data)
{
int len = data.Length;
int toAdd = (16 - len % 16);
for (int i = 0; i < toAdd; i++)
{
data += (char)toAdd;
}
return data;
}
当我尝试时,会在byte[] final = cipher.DoFinal();
行引发InvalidCipherTextExpression并显示“pad block corrupted”消息。
我测试了我的填充功能,它似乎按预期工作
我试图查看BouncyCastle源代码以查找我的错误,我发现最后一个块没有任何填充,这就是导致错误的原因。所以我想知道我是否在其他地方做错了什么,因为它可能不是来自填充物
也许是输入字符串,它是从http服务器检索到的:
// grab te response and print it out to the console along with the status code
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
return new StreamReader(response.GetResponseStream()).ReadToEnd();
我想要达到的目标与此完全相同:C# Decrypting AES/ECB Paddded Using PKCS#5
但是因为提问者没有尝试任何东西,所以没有任何笨蛋......
提前致谢,我真的很抱歉我的英语不好。
答案 0 :(得分:0)
您有一个不完整的密文 - 使用AES-128加密的数据将始终是128/8 = 16字节的倍数。即Last block incomplete in decryption
表示你有127个字节的密文而不是128个。
如评论中所述,您不得在解密之前填写密文。 “它有效”,因为你的功能实际上没有填充任何东西 - 因为上面突出显示的原因。
你确定你使用的是相同的“位数”AES吗? (例如,您可能使用AES-192解密AES-128密文)
P.S。在一个不相关的说明中,cipher.Init(false, new KeyParameter(Encoding.UTF8.GetBytes(KEY)));
看起来也很可疑。你确定它不是Base64之类的吗?