C# "Bad Data" exception when decrypting encrypted file

11,233

Solution 1

Here:

    cryptostream.Write(byteArrayInput, 0, byteArrayInput.Length);
    fsIn.Close();
    fsOut.Close();

You're closing fsOut directly, without closing cryptostream. That means the crypto stream doesn't get the chance to flush any final blocks etc.

Additionally:

  • Use using statements instead of manually calling Close or Dispose
  • You're currently calling Read once, and assuming it will read all the data - you're not checking the return value. (You're also removing the last byte of the input file for some reason... why?) In general, you should loop round, reading into a buffer and then writing out however many bytes you read, until the Read method returns 0. If you're using .NET 4, Stream.CopyTo is your friend.

Solution 2

  objCryptStream.CopyTo(stream);

Worked for me, complete code is

 public static string DecryptString(string encriptedText, string key)
   {

       try
       {


           //Convert the text into bytest
           byte[] ecriptedBytes = System.Convert.FromBase64String(encriptedText);

           // Create a memory stream to the passed buffer
           MemoryStream objMemStream = new MemoryStream(ecriptedBytes);

           //Set the legal keys and initialization verctors
           objCrptoService.Key = GetLegalsecretKey(key);
           objCrptoService.IV = GetLegalIV();

           // Create a CryptoStream using the memory stream and the cryptographic service provider  version
           // of the Data Encryption stanadard algorithm key
           CryptoStream objCryptStream = new CryptoStream(objMemStream, objCrptoService.CreateDecryptor(), CryptoStreamMode.Read);

           // Create a StreamReader for reading the stream.
           //StreamReader objstreamReader = new StreamReader(objCryptStream);
           MemoryStream stream = new MemoryStream();
           objCryptStream.CopyTo(stream);
           stream.Position = 0;
           StreamReader R = new StreamReader(stream);
           string outputText = R.ReadToEnd();

           // Close the streams.
           R.Close();
           objCryptStream.Close();
           objMemStream.Close();

           return outputText;
       }
       catch (Exception exc)
       {
           return "";
       }
   }
Share:
11,233
Raphael
Author by

Raphael

I love C# .NET so much I forced my company to develop in Xamarin. When I'm not coding in C#, I build responsive websites using Javascript because I hate CSS. When I'm not coding at all, I make music, which is sort of like coding as well. I collect Yeezy sneakers. My life is not that interesting

Updated on June 04, 2022

Comments

  • Raphael
    Raphael almost 2 years

    Hey I'm very new to encryption and decryption, or even the c# language to be honest. Basically, I have a tcp chat server that "saves" logs and encrypts the text file. This is how I encrypt (based from the MSDN sample):

    public static void EncryptFile(string strInputFileName, string strOutputFileName, string strKey)
    {
        FileStream fsIn = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read);
        FileStream fsOut = new FileStream(strOutputFileName, FileMode.Create, FileAccess.Write);
    
        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        des.Key = ASCIIEncoding.ASCII.GetBytes(strKey);
        des.IV = ASCIIEncoding.ASCII.GetBytes(strKey);
    
    
        ICryptoTransform desencrypt = des.CreateEncryptor();
        CryptoStream cryptostream = new CryptoStream(fsOut, desencrypt, CryptoStreamMode.Write);
    
        byte[] byteArrayInput = new byte[fsIn.Length - 1];
        fsIn.Read(byteArrayInput, 0, byteArrayInput.Length);
        cryptostream.Write(byteArrayInput, 0, byteArrayInput.Length);
    
        fsIn.Close();
        fsOut.Close();
    }
    

    The method success fully encrypts files. This is my decrypt method:

    public static void DecryptFile(string strInputFileName, string strOutputFileName, string strKey)
    {
        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        des.Key = ASCIIEncoding.ASCII.GetBytes(strKey);
        des.IV = ASCIIEncoding.ASCII.GetBytes(strKey);
    
        byte[] te = new byte[1024];
        FileStream fsRead = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read);
        ICryptoTransform desdecrypt = des.CreateDecryptor();          
    
        CryptoStream cryptostream = new CryptoStream(fsRead, desdecrypt, CryptoStreamMode.Read);
        StreamWriter fsDecrypted = new StreamWriter(strOutputFileName);            
    
        fsDecrypted.Write(new StreamReader(cryptostream).ReadToEnd());//This is where the "Bad Data" occurs.
        fsDecrypted.Flush();
        fsDecrypted.Close();
        fsRead.Close();
    }
    

    And when I inspect the cryptostream object, it says that it has thrown an exception, "Stream does not support seeking".

    Any help would be greatly appreciated!