[英]CryptographicEngine.Decrypt method return an error in a c# UWP app
我不明白为什么这段代码会返回错误:
Data error (cyclic redundancy check). (Exception from HRESULT: 0x80070017)
因为Silverlight Platform中的等效代码不会引发异常。这是下面的UWP c#代码:
public static async Task<Stream> Decrypt(Stream source,
IBuffer easKey,IBuffer IV, byte[] masterKey)
{
try
{
SymmetricKeyAlgorithmProvider aes = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
if ((source.Length % aes.BlockLength) != 0)
{
var temp = new MemoryStream();
temp.SetLength(source.Length + (aes.BlockLength - source.Length % aes.BlockLength));
source.CopyTo(temp);
source = temp;
}
CryptographicKey symmKey = aes.CreateSymmetricKey(easKey);
var sarray = ((MemoryStream)source).ToArray();
IBuffer resultBuffer = CryptographicEngine.Decrypt(symmKey,sarray.AsBuffer(), IV);
byte[] result;
CryptographicBuffer.CopyToByteArray(resultBuffer, out result);
return new MemoryStream(result);
}
catch (Exception e)
{
await new MessageDialog(e.StackTrace, e.Message).ShowAsync();
}
return null;
}
vcsjones在您的问题下的评论中占据了重要位置。 如果您检查数据长度是否为块长度的偶数倍,而不是块长度的倍数,则应立即抛出异常,表明数据不正确。 因为用AES加密的任何东西都不会导致与块长度的偶数倍不同的东西。 即使是空字符串也会产生一个1块长的密文。
话虽如此,您已经准备好使用PKCS7填充解密块的加密算法。 另一方面,如果得到一个较短的块,则将其复制到正确长度的MemoryStream中。 我假设最后一个字节为零。 因此,该块不是有效的密文块。
PKCS7填充将X字节数相加以获得块大小的偶数倍,并且这些字节中的每个字节都是相同的数。 因此,如果块大小为16个字节(128位),而最后一个块仅包含10个字节的实际信息,则将最后6个字节填充为0x06 0x06 0x06 0x06 0x06 0x06。
不过,关键是在加密之前,将此填充添加到纯文本中。 您不能简单地将填充添加到部分密文的末尾并能够对其进行解密。 这些强加密算法的本质是,块中任何给定位的最终值实际上是该块中其他所有位的函数。 因此,如果丢失了该块的任何部分,则将无法挽回地丢失整个块。
现在,如果您确实确实需要尽可能多地解密消息,则丢弃部分块(无论如何我都不会像上面提到的那样解密它)。 用0x10的完整块替换它(重复16次)。 这告诉算法,您有正好为X数量的纯文本块,并且对于每个PKCS7,您正好添加了整个与PKCS7兼容的填充块。 这将允许您解密除消息的部分块以外的所有块。
编辑说您应该使用相同的密钥对填充块进行加密,并将其附加到密文上,以便能够解密除部分块以外的所有块。 但这毕竟不是最简单的方法。 在您的位置,我只需将解密设置更改为padding = None。 再次丢弃该部分块,其余部分只要没有损坏就应该解密而没有问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.