exception - "Length of the data to decrypt is invalid."Rijndael 解密期间的异常

标签 exception rijndaelmanaged

我收到“要解密的数据长度无效”。当我尝试解密内存流时出现异常。我是初学者,无法弄清楚什么是错的。怎么了?

public bool EncryptStream()
    {

        string password = @"myKey123"; // Your Key Here
        UnicodeEncoding UE = new UnicodeEncoding();
        byte[] key = UE.GetBytes(password);

        s_EncryptedStream = new MemoryStream();
        int NoOfBytes;
        byte[] b_Buffer = new byte[8192];

        s_MemoryStream.Seek(0, SeekOrigin.Begin);

        RijndaelManaged RMCrypto = new RijndaelManaged();

        s_CrytpoStream = new CryptoStream(s_EncryptedStream,
            RMCrypto.CreateEncryptor(key, key),
            CryptoStreamMode.Write);

        while (s_MemoryStream.Length < s_MemoryStream.Position)
        {
            NoOfBytes = s_MemoryStream.Read(b_Buffer, 0, 8192);
            s_CrytpoStream.Write(b_Buffer, 0, NoOfBytes);
        }

        s_MemoryStream.Seek(0, SeekOrigin.Begin);

        while (s_EncryptedStream.Position < s_EncryptedStream.Length)
        {
            NoOfBytes = s_EncryptedStream.Read(b_Buffer, 0, 8192);
            s_MemoryStream.Write(b_Buffer, 0, NoOfBytes);

        }
        s_CrytpoStream.Flush();
        s_CrytpoStream.Close();

        return true;

    }


    public bool DecryptStream()
    {


        string password = @"myKey123"; // Your Key Here

        UnicodeEncoding UE = new UnicodeEncoding();
        byte[] key = UE.GetBytes(password);

        int NoOfBytes;
        byte[] b_Buffer = new byte[8192];

        s_DecryptedStream = new MemoryStream();


        RijndaelManaged RMCrypto = new RijndaelManaged();

        s_CrytpoStream = new CryptoStream(s_MemoryStream,
            RMCrypto.CreateDecryptor(key, key),
            CryptoStreamMode.Read);

        s_MemoryStream.Seek(0, SeekOrigin.Begin);

        while (s_MemoryStream.Length > s_MemoryStream.Position)
        {
            NoOfBytes = s_CrytpoStream.Read(b_Buffer, 0, 8192);
            s_DecryptedStream.Write(b_Buffer, 0, NoOfBytes);
        }

        s_DecryptedStream.Seek(0, SeekOrigin.Begin);
        s_MemoryStream.Seek(0, SeekOrigin.Begin);

        while (s_DecryptedStream.Position < s_DecryptedStream.Length)
        {
            NoOfBytes = s_DecryptedStream.Read(b_Buffer, 0, 8192);
            s_MemoryStream.Write(b_Buffer, 0, NoOfBytes);

        }

        s_CrytpoStream.Flush();
        s_CrytpoStream.Close();

        return true;

    }

最佳答案

首先,这个 while 循环条件永远不会正确:

while (s_MemoryStream.Length < s_MemoryStream.Position)

位置怎么会超出长度?

复制流的常用模式不是使用流的长度,而是重复读取,直到返回的值不为正。无论如何,当您在此代码中执行两次此操作时,您不妨将其封装:
public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[8192];
    int read;
    while ( (read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, read);
    }
}

最好使用 using语句来清理字符串。此外,Encoding.Unicode属性意味着您不必创建新的 UnicodeEncoding你自己。另外,我一般发现设置Position属性比使用 Seek 更具可读性.最后,如果返回值总是 true,则方法返回值毫无意义。 .因此,您的代码将变为:
public void EncryptStream()
{
    string password = @"myKey123"; // Your Key Here
    byte[] key = Encoding.Unicode.GetBytes(password);

    s_EncryptedStream = new MemoryStream();
    s_MemoryStream.Position = 0;

    RijndaelManaged RMCrypto = new RijndaelManaged();

    using (Stream crytpoStream = new CryptoStream(s_EncryptedStream,
        RMCrypto.CreateEncryptor(key, key),
        CryptoStreamMode.Write))
    {
        CopyStream(s_MemoryStream, cryptoStream);
    }

    s_MemoryStream.Position = 0;
    s_EncryptedStream.Position = 0;
    CopyStream(s_EncryptedStream, s_MemoryStream);
}

public void DecryptStream()
{
    string password = @"myKey123"; // Your Key Here
    byte[] key = Encoding.Unicode.GetBytes(password);

    s_DecryptedStream = new MemoryStream();
    s_MemoryStream.Position = 0;

    RijndaelManaged RMCrypto = new RijndaelManaged();

    using (Stream crytpoStream = new CryptoStream(s_MemoryStream,
        RMCrypto.CreateDecryptor(key, key),
        CryptoStreamMode.Read))
    {
        CopyStream(cryptoStream, s_DecryptedStream);
    }

    s_DecryptedStream.Position = 0;
    s_MemoryStream.Position = 0;

    CopyStream(s_DecryptedStream, s_MemoryStream);
}

即使修改了这段代码,你也感觉这里有太多的非局部变量。我不明白为什么这些都应该在实例变量中。使要加密或解密的流成为一个参数(连同密码),并返回一个带有加密/解密数据的内存流,或者只是一个字节数组。

关于exception - "Length of the data to decrypt is invalid."Rijndael 解密期间的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/845971/

相关文章:

javascript - 当您无法控制时如何规避同源策略错误

c# - 用 C# 加密 AES 以匹配 Java 加密

java - 记录 Spring 通过 @Async 注释创建的线程抛出的 RuntimeException

exception - Compact Framework 非特定文化异常消息

java - 与 “JAVA exception handling mindset”相比, “C++ exception handling”是什么?

java - 为什么会出现 java.util.ConcurrentModificationException?

c# - RijndaelManaged Decryption - 如何优雅地删除 padding/0?

C# Rijndael 解密返回额外的问号字符

c# - .NET 加密类的线程安全性?

.net - 当字符串 > 751 个字符时为 "Length of the data to decrypt is invalid"