Exception thrown when CryptoStream instance closed

1.9k Views Asked by At

I have a DecryptString function that uses the RijndaelManaged Cipher. It works 99.999% of the time but very occationally it throws an "IndexOutOfRangeException" exception with the message of "Index was outside the bounds of the array." when it tries to close the cryptoStream in the finally block.

When it does stop working it will stop working for a period of 20 minutes or so and then start working again with not obvious explination. One lead I do have is that it only st

public string DecryptString(string InputText, string Password)
        {
            //checkParamSupplied("InputText", InputText);
            checkParamSupplied("Password", Password);

            MemoryStream memoryStream = null;
            CryptoStream cryptoStream = null;

            try
            {
                RijndaelManaged RijndaelCipher = new RijndaelManaged();

                byte[] EncryptedData = Convert.FromBase64String(InputText);

                byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());

                PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);

                // Create a decryptor from the existing SecretKey bytes.
                ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));

                memoryStream = new MemoryStream(EncryptedData);

                // Create a CryptoStream. (always use Read mode for decryption).
                cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);

                // Since at this point we don't know what the size of decrypted data
                // will be, allocate the buffer long enough to hold EncryptedData;
                // DecryptedData is never longer than EncryptedData.
                byte[] PlainText = new byte[EncryptedData.Length];

                // Start decrypting.
                int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length);

                // Convert decrypted data into a string. 
                string DecryptedData = Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);

                // Return decrypted string.   
                return DecryptedData;
            }
            catch (Exception ex)
            {
                throw;
            }
            finally
            {
                //Close both streams.
                memoryStream.Close();
                cryptoStream.Close();
            }
        }
1

There are 1 best solutions below

1
On

One thing I do notice is that you're closing the cryptoStream's underlying stream before you close the cryptoStream itself in your finally block - perhaps you should reverse these two statements?