Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Save Zip File in Access Database With File Encryption in C#

0.00/5 (No votes)
7 Jun 2014 2  
Saving zip files in access database with encrypting bytes when file saved in access database and decrypting bytes when extracting files from database . . .

Introduction

You can save various types of files in Access database. You should convert files to bytes and then save bytes in to OLE Object type filed in Microsoft Access Database Table. In this article, we saved zip files in Access database. But before saving file in database by using a method, I encrypt file for more security and when saving a file on the hard disk, decrypt file with other method to use file.

If the file is not decoded at the time of publication, then users cannot get the main file content. This method is a recommended way to secure documents. If hackers access the database, they cannot simply use the data.

Requirements

You will need the following tools before using the class, those tools are needed for development:

  • Visual Studio .NET 2008 or higher
  • .NET framework 3.0 or higher

Using the Code

At first, you should create a Microsoft Access database 2000 or 2003. Your database should have a table with below fields (See Figure 1):

  • ZipFIleID AutoNumber
  • ZipFileName Text
  • ZipFileContent OLE Object

Access database table fields

Figure 1

Then we need to create a Visual Studio 2008 Windows application project. The next step we should add dataset to our project and Data source dataset, is a Microsoft Access file that we created (See Figure 2).

dataset for saving zip file to access database

Figure 2

This dataset has a method to fetch a record. The input parameter to this method is the record ID. You can see the Query as below:

SELECT ZipFIleID, ZipFileName, ZipFileContent
FROM tblZipFles
WHERE (ZipFIleID = ?)
ORDER BY ZipFIleID DESC>

Next, we create a form and then put into the form, following objects (See Figure 3):

  1. Two Buttons (To insert a file in the database and retrieve files from database)
  2. One ComboBox (To show list of drives to select by users)
  3. TextBox (To enter the File ID by users)
  4. ListBox (To show list of files in database)

add files to access database with C#

Figure 3

When the user clicks on the key inserted, the file selection window is displayed. Code shown as below:

private void Btn_AddFileToDB_Click(object sender, EventArgs e)
{
    OpenFileDialog openFileDialog1 = new OpenFileDialog();
    openFileDialog1.Filter = "ZIP Files (.zip)|*.zip";
    openFileDialog1.FilterIndex = 1;
    openFileDialog1.ShowDialog();
    
    if (openFileDialog1.FileName.Trim() != "")
    {
        Byte[] Byt_ZipFile = null;
        Byt_ZipFile = UDF_ZipToByte(openFileDialog1.FileName.Trim());
        Class_ByteEncryption BytEnc = new Class_ByteEncryption(Byt_ZipFile);// Encrypt Bytes . . .
        BytEnc.UDF_EncryptBytes();
        Byt_ZipFile = BytEnc.Byt_CryptedBytes;
        UDF_SaveFileToDB(openFileDialog1.SafeFileName.Trim()/*Get Just FileName with Extention*/, Byt_ZipFile);
    }           
}

By the following method, selected file is converted to bytes (In the previous method, this method is called):

 public static byte[] UDF_ZipToByte(String filePath)
{
    byte[] buffer;
    FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
    try
    {
        int length = (int)fileStream.Length;  // get file length
        buffer = new byte[length];            // create buffer
        int count;                            // actual number of bytes read
        int sum = 0;                          // total number of bytes read
        
        // read until Read method returns 0 (end of the stream has been reached)
        while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
            sum += count;  // sum is a buffer offset for next reading
    }
    finally
    {
        fileStream.Close();
    }
    return buffer;
}

Before files are stored in the database, we should encode bytes. To do this, we use the method UDF_EncryptBytes in Class_ByteEncryption classes.

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Security.Cryptography;
using System.Xml.Linq;

public class Class_ByteEncryption
{
    Byte[] Byt_InputBytes = null;

    public Class_ByteEncryption(Byte[] Byt_InpBytes)
    {
        Byt_InputBytes = Byt_InpBytes;
    }

    // ???????
    public void UDF_EncryptBytes()
    {
        byte[] IV = new byte[8] { 10, 11, 85, 7, 14, 76, 10, 22 };
        string cryptokey = "lar ltc";
        byte[] mystring = Byt_InputBytes;
        byte[] my_buffer = mystring;

        TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

        des.Key = md5.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(cryptokey));
        des.IV = IV;

        byte[] codebuffer = des.CreateEncryptor().TransformFinalBlock(my_buffer, 0, my_buffer.Length);

        Byt_InputBytes = codebuffer;
    }

    public Byte[] Byt_CryptedBytes
    {
        get
        {
            return Byt_InputBytes;
        }
    }
}

After conversion to bytes, by the following method and dataset, can be stored in the database:

private void UDF_SaveFileToDB(String Str_FileName , Byte[] Byt_ZipFile1)
{
    DataSetTableAdapters.tblZipFlesTableAdapter db = new EncodeDecodeZipInDb.DataSetTableAdapters.tblZipFlesTableAdapter();
    db.Insert(Str_FileName.Trim(), Byt_ZipFile1);
    UDF_GetFilesList();
    MessageBox.Show("File Saved In DB . . .");
}

With the below method, you can set drive lists to ListBox:

private void UDF_GetHardDriveList()
{
    String[] DriveList = System.IO.Directory.GetLogicalDrives();
    foreach (string str in DriveList)
     {
         comboBox1.Items.Add(str);
         try
         {
             comboBox1.SelectedIndex = 0;
         }
         catch { }
     }
}

By the following method, insert data records in the database are displayed:

private void UDF_GetFilesList()
{
    DataSetTableAdapters.tblZipFlesTableAdapter db = new EncodeDecodeZipInDb.DataSetTableAdapters.tblZipFlesTableAdapter();
    DataSet.tblZipFlesDataTable dt = new DataSet.tblZipFlesDataTable();
    db.Fill(dt);
    listBox1.Items.Clear();
    foreach (DataRow Row in dt.Rows)
    {
        listBox1.Items.Add("Code = " + Row[0].ToString() + " - Name = " + Row[1]);
    }
}

To publish a file and save it in the selected drive, you should be clicking on the Export Zip button. Also, before you click, you must enter the file ID from (that is selected from list box) in a text field and select a drive (See Figure 4).

Select File To Decode

Figure 4

When clicked, the following method is run:

private void Btn_SaveToFile_Click(object sender, EventArgs e)
{
    if (textBox1.Text.Trim() == "")
    {
        MessageBox.Show("Please Enter Zip File Code From List");
    }
    else
    {
        try
        {
            DataSetTableAdapters.tblZipFlesTableAdapter db = new EncodeDecodeZipInDb.DataSetTableAdapters.tblZipFlesTableAdapter();
            DataSet.tblZipFlesDataTable dt = new DataSet.tblZipFlesDataTable();
            db.FillBy(dt, int.Parse(textBox1.Text.Trim()));
            Class_ByteDecryption DecBytes = new Class_ByteDecryption((Byte[])dt[0][2]);
            DecBytes.UDF_DencryptBytes();
            UDF_SaveBinaryDateToFile(dt[0][1].ToString(), DecBytes.Byt_DcryptedBytes);//Saving file to db
            MessageBox.Show("File Saved . . . ");
        }
        catch { MessageBox.Show("Please Enter Valid Code From List. . ."); }
    }
}

The following method is called to save file to disk:

/// <summary>
/// Save Record To Database
/// </summary>
/// <param name="Str_FileName"></param>
/// <param name="Byt_ZipFile1"></param>
private void UDF_SaveFileToDB(String Str_FileName , Byte[] Byt_ZipFile1)
{
    DataSetTableAdapters.tblZipFlesTableAdapter db = new EncodeDecodeZipInDb.DataSetTableAdapters.tblZipFlesTableAdapter();
    db.Insert(Str_FileName.Trim(), Byt_ZipFile1);
    UDF_GetFilesList();
    MessageBox.Show("File Saved In DB . . .");
}

Before file is saved in drive, bytes should decode to user which can be used in saved file. Code decoding is performed by the UDF_DencryptBytes method in Class_ByteDecryption class.

public class Class_ByteDecryption
{
    Byte[] Byt_InputBytes = null;
    public Class_ByteDecryption(Byte[] Byt_InpBytes)
    {
            Byt_InputBytes = Byt_InpBytes;
    }
public void UDF_DencryptBytes()
    {
        byte[] IV = new byte[8] { 10, 11, 85, 7, 14, 76, 10, 22 };
        string cryptokey = "lar ltc";
        byte[] codedstring;
        codedstring = Byt_InputBytes;
        byte[] my_buffer = codedstring;
        TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        des.Key = md5.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(cryptokey));
        des.IV = IV;
        byte[] codedbuffer = des.CreateDecryptor().TransformFinalBlock(my_buffer, 0, my_buffer.Length);
        Byt_InputBytes = codedbuffer;
    }

public Byte[] Byt_DcryptedBytes
    {
        get
        {
            return Byt_InputBytes;
        }
    }
}

If you see the error at compile time, in 64-bit Windows, make the following changes (See Figure 5):

Access Db

Figure 5

App.config Setting

Application configuration files contain settings specific to an application. This file contains configuration settings that the common language runtime reads (such as assembly binding policy, remote objects, and so on), and settings that the application can read.

Your Project connection string should be placed in app.config file. This file is in XML format. With this file, you can change the connection string. You can create this file automatically with Visual Studio. You can store inside it connection string that you may want to change without having to change code.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    <connectionStrings>
        <add name="EncodeDecodeZipInDb.Properties.Settings.ZipFileDBConnectionString"
            connectionString="Provider=Microsoft.Jet.OLEDB.4.0;
            Data Source=|DataDirectory|\ZipFileDB.mdb"  providerName="System.Data.OleDb" />
    </connectionStrings>
</configuration>

Meanwhile, you can define a static route to connect to the database:

<add name="EncodeDecodeZipInDb.Properties.Settings.ZipFileDBConnectionString"
            connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\ZipFileDB.mdb"
            providerName="System.Data.OleDb" />

Conclusion

Now you can save your document in Access database safely. In the end, I note that this is only a suggestion. Also, for more security, you can change the encoding algorithm. The key to change is one of those ways.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here