AesCryptoServiceProvider 抛出加密异常

Posted

技术标签:

【中文标题】AesCryptoServiceProvider 抛出加密异常【英文标题】:AesCryptoServiceProvider throws Cryptographic exception 【发布时间】:2015-01-28 11:34:49 【问题描述】:

我正在为学校做一些项目。我正在与 TcpClient 和 TcpListener 进行服务器客户端通信。一开始我在服务器上创建 AES 密钥,然后使用 RSA 将其发送给客户端。我这里没有问题。但是,当我尝试在客户端加密字符串然后在服务器上对其进行加密时,出现异常。

    填充无效,无法移除

服务器代码:

Byte[] bytes = new Byte[1024];
String data = null;
clientStream.Read(bytes, 0, bytes.Length); // preberemo iz streama
//Array.Clear(bytes, 0, bytes.Length);
// string temp = Encoding.UTF8.GetString(bytes11);
//temp = temp.Replace("\0", "");
//yte[] bytes = Encoding.UTF8.GetBytes(temp);
using (MemoryStream msEncrypt = new MemoryStream())


    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, aes.CreateDecryptor(aes.Key,aes.IV), CryptoStreamMode.Write))
    

        //StreamWriter swEncrypt = new StreamWriter(csEncrypt);

        csEncrypt.Write(bytes, 0, bytes.Length);


    
    byte[] encrypted = msEncrypt.ToArray();
    string enc = Encoding.UTF8.GetString(encrypted, 0, encrypted.Length);

客户端代码:

byte[] messg = Encoding.UTF8.GetBytes(messig);
// dobimo client stream
string enc = null;
using (MemoryStream msEncrypt = new MemoryStream())



    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, aes.CreateEncryptor(aes.Key, aes.IV), CryptoStreamMode.Write))
    

        csEncrypt.Write(messg,0,messg.Length);
    
    byte[] encrypted = msEncrypt.ToArray();
    enc = Encoding.UTF8.GetString(encrypted, 0, encrypted.Length);

byte[] data = new byte[1024];
data = Encoding.UTF8.GetBytes(enc);
//CryptoStream CryptStream = new CryptoStream(stream,aes.CreateEncryptor(aes.Key, aes.IV),CryptoStreamMode.Write);


stream.Write(data, 0, data.Length); // pošljem sporočilo

尝试使用时服务器出现异常 msEncrypt.ToArray();

但是,如果我以动态方式分配 Byte[],或者我删除所有空值,我会收到一个异常提示“输入数据不是一个完整的块”。

【问题讨论】:

【参考方案1】:

我已经解决了这个问题:

aes.Padding = PaddingMode.Zeros;

【讨论】:

我不会投反对票(还),请阅读我的答案并决定你如何处理这个答案。【参考方案2】:

问题很可能是Encoding.UTF8.GetString(encrypted, 0, encrypted.Length);。这意味着代码将可以具有任何值的字节视为文本编码。这意味着如果字节不代表有效的文本,它们要么改变值(例如用问号代替)要么一起被忽略。

需要使用base 64编码将密文视为实际文本。在当今时代,密文始终是二进制的(通常以字节为单位)。


请注意,使用PaddingMode.Zeros 并不能解决问题。如果使用 UTF-8 解码,可能会从密文中删除信息。 PaddingMode.Zeros 只是去除异常,并没有解决信息丢失的底层问题。

【讨论】:

嗯,可能是这样,但 PaddingMode.Zeroes 似乎对我有用......我不再有任何异常......虽然我得到了太多信息,因为我有 byte[1024] 数组。 ..我通过从读取流中获取 int 大小然后将数组复制到实际大小的数组来解决这个问题... 嗯,是的,这至少 一样重要。尝试解密太大的密文会产生相同的后果。您现在是否已经为 PKCS#7(默认)填充工作了?

以上是关于AesCryptoServiceProvider 抛出加密异常的主要内容,如果未能解决你的问题,请参考以下文章

测试来自 C# 的 AES-NI 指令