Thread: Exception of file encryption using c#

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    9

    Exception of file encryption using c#

    Hi,
    Currently i am doing a project related to file encryption using c#. I new to the c# programming actually. I used microsoft visual c# express 2008. I had combine some of the code from internet reference, but i am facing a problem where program highlight "cs.Close();" and show
    IndexOutOfRangeException was unhandled when decrypt button is clicked. The file decryption is unsuccessful due to this exception i think. Is there anybody know how to solve for this problem? Any suggestion on how to change the code? The code of my project is as below:
    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Security.Cryptography;
    using System.IO;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                openFD.Title = "Insert a File";
                openFD.InitialDirectory = "F://";
                openFD.FileName = "";
                DialogResult result = openFD.ShowDialog();
                string filename;
                filename = openFD.FileName;
                if (result == DialogResult.OK)
                {
    
                    textBox2.Text = filename;
    
                }
                else
                {
                    return;
                }
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                string password = textBox1.Text;
                string salt_value = "abcdefg";
                string hash = "sha1";
                int passwordIterations = 10;
                string initVector = "@1A2C5D1F286AB54";
                int keySize = 128;
                Encrypt(@"filename", @"C:\Encrypted.ppt", password, salt_value, hash, passwordIterations, initVector, keySize);
               
            }
            public static void Encrypt(string _inputFile, string _outputFile, string password, string salt_value, string hash, int passwordIteration, string initVector, int keySize)
            {
                if (password.Length > 8)
                    password = password.Substring(0, 8);
                else if (password.Length < 8)
                {
                    int add = 8 - password.Length;
                    for (int i = 0; i < add; i++)
                        password = password + i;
                }
                byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
                byte[] salt_valueBytes = Encoding.ASCII.GetBytes(salt_value);
                PasswordDeriveBytes key = new PasswordDeriveBytes(password, salt_valueBytes, hash, passwordIteration);
                byte[] keyBytes = key.GetBytes(keySize / 8);
    
                FileStream fsCrypt = new FileStream(_outputFile, FileMode.Create);
    
    
                RijndaelManaged RMCrypto = new RijndaelManaged();
                RMCrypto.Mode = CipherMode.CBC;
                CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(keyBytes, initVectorBytes), CryptoStreamMode.Write);
    
                FileStream fsIn = new FileStream(_inputFile, FileMode.OpenOrCreate);
                int data;
                while ((data = fsIn.ReadByte()) != -1)
                    cs.WriteByte((byte)data);
    
                fsIn.Close();
                cs.Close();
                fsCrypt.Close();
                cs = null;
                fsIn = null;
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                openFD.Title = "Insert a File";
                openFD.InitialDirectory = "F://";
                openFD.FileName = "";
                DialogResult result = openFD.ShowDialog();
                string filename;
                filename = openFD.FileName;
                if (result == DialogResult.OK)
                {
    
                    textBox3.Text = filename;
    
                }
                else
                {
                    return;
                }
            }
    
            private void button4_Click(object sender, EventArgs e)
            {
                string password = textBox1.Text;
                string salt_value = "abcdefg";
                string hash = "sha1";
                int passwordIterations = 10;
                string initVector = "@1A2C5D1F286AB54";
                int keySize = 128;
                Decrypt(@"filename", @"C:\Decrypted.ppt", password, salt_value, hash, passwordIterations, initVector, keySize);
               
            }
    
            public static void Decrypt(string _inputFile, string _outputFile, string password, string salt_value, string hash, int passwordIteration, string initVector, int keySize)
            {
                if (password.Length > 8)
                    password = password.Substring(0, 8);
                else if (password.Length < 8)
                {
                    int add = 8 - password.Length;
                    for (int i = 0; i < add; i++)
                        password = password + i;
                }
                byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
                byte[] salt_valueBytes = Encoding.ASCII.GetBytes(salt_value);
                PasswordDeriveBytes key = new PasswordDeriveBytes(password, salt_valueBytes, hash, passwordIteration);
                byte[] keyBytes = key.GetBytes(keySize /8);
    
                FileStream fsCrypt = new FileStream(_outputFile, FileMode.Create);
    
                RijndaelManaged RMCrypto = new RijndaelManaged();
                RMCrypto.Mode = CipherMode.CBC;
                CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(keyBytes, initVectorBytes), CryptoStreamMode.Write);
    
    
    
    
                FileStream fsIn = new FileStream(_inputFile, FileMode.OpenOrCreate);
                int data;
                while ((data = fsIn.ReadByte()) != -1)
                    cs.WriteByte((byte)data);
    
                cs.Close();~IndexOutOfRangeException was unhandled
                fsIn.Close();
                fsCrypt.Close();
    
                cs = null;
                fsIn = null;
                fsCrypt = null;
            }
        }
    }
    The source code can be download from the link below:
    http://cid-1caedb18b83acfa1.skydrive...Encryption.rar
    If I am not disturbing,please guide. Thanks a lot!

    Regards,
    sf

  2. #2
    Registered User
    Join Date
    Jun 2003
    Posts
    129
    Code:
    CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(keyBytes, initVectorBytes), CryptoStreamMode.Write);
    
                FileStream fsIn = new FileStream(_inputFile, FileMode.OpenOrCreate);
                int data;
                while ((data = fsIn.ReadByte()) != -1)
                    cs.WriteByte((byte)data);
    
                cs.Close();~IndexOutOfRangeException was unhandled
                fsIn.Close();
                fsCrypt.Close();
    
                cs = null;
                fsIn = null;
                fsCrypt = null;
    you seem to have cs further down. In fact, remove all the null lines at the end, not needed, you've already 'killed' them by doing Close(), and it's done when you reach the last } as well.

    close your while loop just before the close with brackets. One, it's a little easier to follow the flow, two, just makes sure!

    restructured:

    Code:
    using(CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(keyBytes, initVectorBytes), CryptoStreamMode.Write))
    {
      using(FileStream fsIn = new FileStream(_inputFile, FileMode.OpenOrCreate))
      {
        int data;
        while ((data = fsIn.ReadByte()) != -1)
        {
          cs.WriteByte((byte)data);
        }
      }
    }
    fsCrypt.Close();
    After doing this, if there is still an error, it should appear on the cs.writebyte line. Which means your while loop condition needs adjusting.
    He who asks is a fool for five minutes, but he who does not ask remains a fool forever.

    The fool wonders, the wise man asks. - Benjamin Disraeli

    There are no foolish questions and no man becomes a fool until he has stopped asking questions. Charles Steinmetz

  3. #3
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Try using try/catch/finally. This is a way to check if there is an error. If there is then the finally code will be executed. If the streams are not null they will close. If they are null then you will get an exception with Close. That is what I thinks happens with your code.

    Note that finally executes even if there NO exception. That is why it is called finally. Whatever happens it executes.

    Code:
           
           CryptoStream cs = null;
           FileStream fsIn = null;
           try
           {
                cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(keyBytes, initVectorBytes), CryptoStreamMode.Write);
                fsIn = new FileStream(_inputFile, FileMode.OpenOrCreate);
                int data;
                while ((data = fsIn.ReadByte()) != -1)
                    cs.WriteByte((byte)data);
             }
             finally
             {
               if (cs != null) cs.Close();~IndexOutOfRangeException was unhandled
               if (fsIn != null)  fsIn.Close();
               if (fsCrypt != null) fsCrypt.Close();
             }

  4. #4
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Try using try/catch/finally. This is a way to check if there is an error. If there is then the finally code will be executed.
    Just wanted to clarify this. The finally block is executed whether there is an error or not. Using DanFraser's method, i.e., taking advantage of the IDisposable interface provided by the Stream classes, accomplishes the same thing: ensuring that the FileStream and CryptoStream are properly closed, in this case on leaving the using() block.

  5. #5
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    To remove unneccessary depth blocks, multiple using's can be written as:
    Code:
    using(...)
    using(...)
    using(...)
    {
      ...
    }
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  6. #6
    Registered User
    Join Date
    Dec 2008
    Posts
    9

    Exception of file encryption using c#

    Thanks you for the suggestion! I really appreciate it. But, i still haven't solve my problem. IndexOutOfRange exception still occurred and i unable to get back the decrypted file.

    Code:
    using(CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(keyBytes, initVectorBytes), CryptoStreamMode.Write))
    {
      using(FileStream fsIn = new FileStream(_inputFile, FileMode.OpenOrCreate))
      {
        int data;
        while ((data = fsIn.ReadByte()) != -1)
        {
          cs.WriteByte((byte)data);
        }
      }
    } ~~~~IndexOutOfRange exception 
    fsCrypt.Close();
    I tried this code for my decryption and now the exception occurred in the last } that i highlight in green color. I felt doubt and actually what's wrong to my code? Is the code that i wrote bad? And is it possible to take out the cs.Close(); in this code?

    For
    Code:
    CryptoStream cs = null;
           FileStream fsIn = null;
           try
           {
                cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(keyBytes, initVectorBytes), CryptoStreamMode.Write);
                fsIn = new FileStream(_inputFile, FileMode.OpenOrCreate);
                int data;
                while ((data = fsIn.ReadByte()) != -1)
                    cs.WriteByte((byte)data);
             }
             finally
             {
               if (cs != null) cs.Close();~~~IndexOutOfRangeException was unhandled
               if (fsIn != null)  fsIn.Close();
               if (fsCrypt != null) fsCrypt.Close();
             }
    Exception still occurred at the line cs.Close(); for this code. And the result is the same, i unsuccess to decrypt the file.

    For
    Using DanFraser's method, i.e., taking advantage of the IDisposable interface provided by the Stream classes, accomplishes the same thing: ensuring that the FileStream and CryptoStream are properly closed, in this case on leaving the using() block.
    I not really understand DanFraser's method and IDisposable interface. Can sir give me a guide on how to use it?


    Sorry for disturbing u all. Any suggestion, please guide. Thanks a lot.

    Regards,
    sf

  7. #7
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Any class that implements the IDisposable interface can be used in a "using" statement. It insures that any resources allocated in that class are properly cleaned up, regardless of exceptions within the using block.

    Why use using?
    C# Using Statement

  8. #8
    Registered User
    Join Date
    Aug 2008
    Posts
    188
    Quote Originally Posted by rags_to_riches View Post
    Any class that implements the IDisposable interface can be used in a "using" statement. It insures that any resources allocated in that class are properly cleaned up, regardless of exceptions within the using block.

    Why use using?
    C# Using Statement
    just to be on the safe side, this statement is correct 99.9% of the time. in multithreaded environments, sometimes the constructor isn't threadsafe, and when it throws an exception it will leak a resource, which calling Dispose() will not clean up.

  9. #9
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Try
    Code:
    if (cs != null) 
    try{
        cs.Close();
    }
    catch(IndexOutOfRangeException e)
    {
        string s = e.toString();
    } //put a break point here and read the value of s. Should give you more information about the error
    Dunno if you get any useful information out of this. Have no idea why Close() can even throw an indexOutOfRange exception

  10. #10
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Your problem is here:
    Code:
    Encrypt(@"filename", @"C:\Encrypted.ppt", password, salt_value, hash, passwordIterations, initVector, keySize);
    The first argument to Encrypt is the file to be encrypted, which doesn't exist, so a 0-length file is created. When you read from the 0-length file, you read EOF immediately. I believe the CryptoStream is attempting to Decrypt (for flushing) what it's got in its buffer on Close, but there's nothing actually there, so it throws the IndexOutOfRange exception.

    In the end, I think you want to swap the first two arguments to Encrypt.
    Last edited by rags_to_riches; 12-23-2008 at 12:31 PM.

  11. #11
    Registered User
    Join Date
    Dec 2008
    Posts
    9

    Exception of file encryption using c#

    Thanks everyone.

    Code:
    Encrypt(@"filename", @"C:\Encrypted.ppt", password, salt_value, hash, passwordIterations, initVector, keySize); The first argument to Encrypt is the file to be encrypted, which doesn't exist, so a 0-length file is created. When you read from the 0-length file, you read EOF immediately. I believe the CryptoStream is attempting to Decrypt (for flushing) what it's got in its buffer on Close, but there's nothing actually there, so it throws the IndexOutOfRange exception. In the end, I think you want to swap the first two arguments to Encrypt.
    The problem of exception is solved and it is related to file to be encrypted as suggested by
    rags_to_riches. But, now the problem is i want to let user be able to browse whatever file they want to encrypt instead of specified the file by myself. Because up to this stage, i just manage to modify it to a specified file name that exist in my computer. The code that i modified and run without any exception and i can get back the original file after i click decrypt button is as below:

    Code:
    Encrypt(@"C:\Presentation1.ppt", @"C:\Encrypted.ppt", password, salt_value, hash, passwordIterations, initVector, keySize);
    Is there anyone know how to further modify my code so that its become flexible and user can choose their desired file to encrypt by using openFileDialog. Other than this, how to modify this code-@"C:\Encrypted.ppt", so that we can get the file name like, for example: "Encrypted Presentation1.ppt"?
    Code:
    if (cs != null) try{ cs.Close(); } catch(IndexOutOfRangeException e) { string s = e.toString(); } //put a break point here and read the value of s. Should give you more information about the error
    About this code, it can solve the exception problem but i cant get the original file back because the actual problem is related to file to be encrypted as mentioned above. Anyway, thanks a lot. I learn a lot from here.

    About the IDisposable interface, it is great but i am now still learning it. I think it will be very useful for my future project.

    Thanks a lot for solving my problem. Here wish u all Happy Merry Christmas.

    Regards,
    sf

  12. #12
    Registered User
    Join Date
    Dec 2008
    Posts
    9
    Hi everyone,
    I solved my problem finally. Thanks for giving me suggestion!

    Regards,
    sf

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  2. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM
  5. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM