Search code examples
c#exceptionencryptionrijndael

C# Encryption System.Security.Cryptography.CryptographicException at CryptoStream.close()


im trying to write an En-/Decrypter in C#. As the title suggests I get a System.Security.Cryptography.CryptographicException at CryptoStream.close(). I haven't find a solution yet. Hope anyone can help.

public static string viaRijndael(byte[] input, string key, string iV)
    {
        Rijndael RijCrypt = Rijndael.Create();

        RijCrypt.Key = System.Text.Encoding.UTF8.GetBytes(Tools.GetMD5Hash(Tools.GetMD5Hash(key))); 

        RijCrypt.IV = System.Text.Encoding.UTF8.GetBytes(Tools.GetMD5Hash(Tools.GetMD5Hash(key)).Substring(0, 16));

        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, RijCrypt.CreateDecryptor(), CryptoStreamMode.Write); 

        cs.Write(input, 0, input.Length); 
        cs.Close(); // System.Security.Cryptography.CryptographicException

        byte[] DecryptedBytes = ms.ToArray();

        return System.Text.Encoding.UTF8.GetString(DecryptedBytes);
    }

Solution

  • MSDN Stream.Close documentation says:

    "This method calls Dispose, specifying true to release all resources. You do not have to specifically call the Close method. Instead, ensure that every Stream object is properly disposed. You can declare Stream objects within a using block (or Using block in Visual Basic) to ensure that the stream and all of its resources are disposed, or you can explicitly call the Dispose method."

    As such I would suggest trying something like the following to handle the disposal of your streams:

    public static string viaRijndael(byte[] input, string key, string iV)
    {
        byte[] decryptedBytes;
    
        using (Rijndael rijCrypt = Rijndael.Create())
        {
            rijCrypt.Key = System.Text.Encoding.UTF8.GetBytes(Tools.GetMD5Hash(Tools.GetMD5Hash(key))); 
    
            rijCrypt.IV = System.Text.Encoding.UTF8.GetBytes(Tools.GetMD5Hash(Tools.GetMD5Hash(key)).Substring(0, 16));
    
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, rijCrypt.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(input, 0, input.Length); 
                }
    
                decrpytedBytes = ms.ToArray();
            }
        }
    
        return System.Text.Encoding.UTF8.GetString(decryptedBytes);
    }
    

    All of this and more is explained in good detail on MSDN for the CryptoStream class.