File ecnryption using DES decrypting garbage - C#

1.1k Views Asked by At

I am trying to write a simple file encrypter in C# using DESCryptoServiceProvider. The file format I am encrypting is .jpg. The encryption appears to look fine, but when I decrypt the encrypted file I get an error message in Windows Photo Viewer.

Here is my code:

public static void Encrypt(string inputFileName, string outputFileName, string key)
    {
        var inputPath = path + "\\" + inputFileName;
        var outputPath = path + "\\" + outputFileName; 

        try
        {
            FileStream fsInput = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
            FileStream fsEncrypted = new FileStream(outputPath, FileMode.Create, FileAccess.Write);

            DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
            DES.Key = ASCIIEncoding.ASCII.GetBytes(key);
            DES.IV = ASCIIEncoding.ASCII.GetBytes(key);
            DES.Padding = PaddingMode.None;

            ICryptoTransform desencrypt = DES.CreateEncryptor();
            CryptoStream cryptostream = new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write);

            byte[] bytearrayinput = new byte[fsInput.Length - 1];
            fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
            cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);

            Console.WriteLine("file encrypted @ {0}", outputFileName);
        }
        catch(Exception ex) 
        {
            Console.WriteLine("catch in encryption: " + ex.Message + "\n\nclosing...");
        }
    }

    public static void Decrypt(string inputFileName, string outputFileName, string key)
    {
        var inputPath = path + "\\" + inputFileName;
        var outputFileHoler = inputFileName.Substring(0, (outputFileName.IndexOf('.') + 4)); //FIX TO REMOVE REGEX
        var outputPath = path + "\\" + outputFileHoler;

        Console.WriteLine(outputPath); //TEMP

        try
        {
            DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
            DES.Key = ASCIIEncoding.ASCII.GetBytes(key);
            DES.IV = ASCIIEncoding.ASCII.GetBytes(key);
            DES.Padding = PaddingMode.None;

            FileStream fsread = new FileStream(inputPath, FileMode.Open, FileAccess.Read);

            ICryptoTransform desdecrypt = DES.CreateDecryptor();
            CryptoStream cryptostream = new CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read);
            StreamWriter fsDecrypted = new StreamWriter(outputPath);

            fsDecrypted.Write(new StreamReader(cryptostream).ReadToEnd());
            fsDecrypted.Flush();
            fsDecrypted.Close();

            Console.WriteLine("file decrypted @ {0}", outputPath);
        }
        catch (Exception ex)
        {
            Console.WriteLine("catch in decryption: " + ex.Message + "\n\nclosing...");
        }
    }

What am I doing wrong?

PS. completely new to cryptography, please forgive me if it is something simple...

1

There are 1 best solutions below

2
On

Do NOT attempt to implement crypto yourself unless you are 100% sure that you know what you are doing. Use well-reviewed, high-level(!) libraries.

You are attempting to use DES. DES is broken and insecure due to insufficient key length. Do not use it.

You are using your key instead of a random value as IV. Depending on how the crypto provider works, this either introduces a small vulnerability or makes your encryption 100% worthless because it leaks your key.

You are not using any padding. This will make it impossible to correctly encrypt/decrypt files that do not exactly fit the block size.

You do not show how you obtain your key. Chances are you do so in an insecure manner. Especially given that you use a string to store it.

The comments by CodesInChaos have pointed out quite a few important points. What is breaking your files is probably the StreamReader, the padding, and the lack of stream flushing/closing. However, again, do NOT attempt to write crypto code - it will be insecure even if you get it working.