“要解密的数据长度无效。” Rijndael 解密期间出现异常

发布于 2024-07-19 14:57:37 字数 2419 浏览 9 评论 0原文

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

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;

    }

I get "Length of the data to decrypt is invalid." exception when i try to decrypt a memory stream. I am beginner, cant figure out whats wrong. whats wrong?

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;

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

脱离于你 2024-07-26 14:57:37

我想出了一个解决方案,并将其发布在我的新博客

constotech.blogspot.com/2009/05/net-encryption-using-symmetryalgorithm.html上

I have come up with a solution and I have it posted on my new Blog

constotech.blogspot.com/2009/05/net-encryption-using-symmetricalgorithm.html

梦开始←不甜 2024-07-26 14:57:37

读取完输入数据后,您可能需要调用 CryptoStream 上的 FlushFinalBlock 方法。 (即 CopyStream 之后的 crytpoStream.FlushFinalBlock()

You may need to call the FlushFinalBlock method on the CryptoStream after you have finished reading the input data. (ie. crytpoStream.FlushFinalBlock() after CopyStream)

合约呢 2024-07-26 14:57:37

首先,这个 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);
}

即使修改此代码后,感觉这里有太多非局部变量。 我不明白为什么其中任何一个都应该在实例变量中。 将要加密或解密的流作为参数(以及密码),并返回包含加密/解密数据的内存流,或者只是一个字节数组。

For a start, this while loop condition is never right:

while (s_MemoryStream.Length < s_MemoryStream.Position)

How can the position be beyond the length?

Rather than using the length of a stream, the usual pattern to copy a stream is to read repeatedly until the value returned isn't positive. As you're doing that twice in this code anyway, you might as well encapsulate it:

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);
    }
}

It's also best to use using statements to clean up strings. Additionally, the Encoding.Unicode property means you don't have to create a new UnicodeEncoding yourself. Also, I generally find that setting the Position property is more readable than using Seek. Finally, there's no point in a method returning a value if it's always going to be true. So, your code would become:

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);
}

Even after amending this code, it feels like you've got way too many non-local variables here. I can't see why any of this should be in instance variables. Make the stream to be encrypted or decrypted a parameter (along with the password) and return a memory stream with the encrypted/decrypted data in, or just a byte array.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文