4

I have some code that decrypts a password with Rijndael

public static string DecryptPassword(string encrypted) {
    using (MemoryStream ms = new MemoryStream())
    using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
    using (ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor(mGlobalKey, mGlobalVector))
    using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Read)) {
        byte[] encryptedBytes = Convert.FromBase64String(encrypted);
        cs.Write(encryptedBytes, 0, encryptedBytes.Length);
        cs.FlushFinalBlock();
        return Encoding.Unicode.GetString(ms.GetBuffer(), 0, (int)ms.Length);
    }
}

The problem is that disposing the cryptostream causes an exception

System.IndexOutOfRangeException : Index was outside the bounds of the array.
at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)  
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)  
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()  
at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)  
at System.IO.Stream.Close()  
at System.IO.Stream.Dispose()  

I found some links to similar problems but no solutions.

Is it safe to just remove the Disposing of the cryptostream or will that just cause the finalizer to blow up at a later time?

adrianm
  • 13,642
  • 4
  • 49
  • 91
  • 2
    Don't know if this helps, but it seams that you are creating the steam in `CryptoStreamMode.Read` mode, and attempting to write to it. – The Scrum Meister Feb 17 '11 at 09:03
  • 1
    Thanks, that solved it. Add it as an answer and I will mark it as such. What happened was that the write caused an exception "Stream does not support writing" but since the finally clause caused another exception I never saw it. – adrianm Feb 17 '11 at 09:22
  • Why do you encrypt passwords? In most use-cases hashing is better suited. – CodesInChaos Feb 17 '11 at 09:38
  • It is a password for a service I connect to. – adrianm Feb 17 '11 at 10:00

2 Answers2

4

You are creating the steam in CryptoStreamMode.Read mode, and attempting to write to it.

Brad Divine
  • 354
  • 2
  • 10
1

Although I couldn’t find a good solution, I found these two work-arounds: A. Don’t make the Encrypt/Decrypt function static (C#) / shared (VB). (You’ll have to change the code to instantiate RijndaelSimple object, and then call the Encrypt/Decrypt functions. Possible cause: NOT sure, but possibly CryptoStream is not using memory stream in a thread-safe way B. It seems that exception is thrown ONLY when cipherText is an empty string. In 1.1, the function used to return an empty string when cipherText is an empty string. So simply add this code as the first line in the Decrypt function: if (string.IsNullOrEmpty(cipherText)) return "";

I went with the option B as // (It would be an efficient soln, as it only fails when cipherText="" // (Efficient as it would still be a static function, and it will Not have to Decrypt when cipherText="")

Paras Shah
  • 11
  • 1