繁体   English   中英

CryptographicEngine.Decrypt方法在ac#UWP应用中返回错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM