小文件导致 OutofMemoryException。

4

我有一个加密的文件,我首先对其进行解密,然后使用MemoryStreamBinaryFormatter尝试将其反序列化,但是当我尝试将反序列化的文件赋值给列表时,会出现OutOfMemoryException(该文件非常小- 17KB)以下是代码:

byte[] encryptedData = File.ReadAllBytes(fileName); 
byte[] result = Decrypt(Algo, key, vector, encryptedData) ;
BinaryFormatter ser = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(result)) {
 try {
     files = ser.Deserialize(ms) as List<IItem>;
  } catch (OutOfMemoryException) {

  } catch (SerializationException) {
     MessageBox.Show("Incorrect password!");
     return;
  }
}

files = ser.Deserialize(ms) as List<IItem>; - 这是导致异常的原因 加密文件大小为1696 解密后大小为1691 - 正常大小。 以下是解密代码

public byte[] Decode(byte[] data)
    {
        string key = ASCIIEncoding.ASCII.GetString(rc2.Key);
        string IV = ASCIIEncoding.ASCII.GetString(rc2.IV);
        ICryptoTransform decryptor = rc2.CreateDecryptor(rc2.Key,rc2.IV);
        StringBuilder roundtrip = new StringBuilder();
        using (MemoryStream msDecrypt = new MemoryStream(data))
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                int b = 0;

                do
                {
                    b = csDecrypt.ReadByte();

                    if (b != -1)
                    {
                        roundtrip.Append((char) b);
                    }
                } while (b != -1);
            }
        }
        byte[] decrypted = ASCIIEncoding.ASCII.GetBytes(roundtrip.ToString());
        return decrypted;
    }

环境MVS,桌面应用程序,x86。 - KofHein
你能打印出 ms.Length 吗(或在调试器中检查)?首先将其反序列化为一个对象,然后在调试器中查看实际类型(鼠标悬停并查看类型,或在监视窗口中使用 variable.GetType() 函数)。 - Ron Beyer
1
解密是什么?它可以将一个17KB的文件转换成17GB...请看结果的长度。 - MineR
1
问题可能是您解密的字节无效,无法适当地反序列化。这个文件是您自己写的吗?您能检查结果是否等于 Serialize 的原始输出吗?StringBuilder 的需求是什么 - 为什么不能直接获取 csDecrypt 的字节? - MineR
1
BinaryFormatter在序列化对象时生成字节。您无法将字节转换为字符,因为不是所有可能的字节值都是有效的Unicode代码点。尤其是在使用ASCII时,它只能表示0到127之间的值。因此,您解密的数据不可避免地会出现损坏,BinaryFormatter会抛出异常。您需要使用字节,请删除加密和解密代码中转换为字符的代码部分。 - Hans Passant
显示剩余2条评论
1个回答

0

@MineR和@HansPassant是正确的,问题在于解密时使用了chars))我已经更改了我的代码

       public byte[] Decode(byte[] data)
    {
        ICryptoTransform decryptor = rc2.CreateDecryptor(rc2.Key,rc2.IV);
        byte[] decrypted = new byte[data.Length];
        using (MemoryStream msDecrypt = new MemoryStream(data))
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
               csDecrypt.Read(decrypted, 0, data.Length);
            }
        }
        return decrypted;
    }

现在它可以正常工作了。感谢大家的答复。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接