简体   繁体   中英

How to Encrypt/Secure MS Access 2007 database file in C#?

I have a program which let me access/add/delete entries from MS Access 2007 file by using a simple database password.

But my goal is to modify my file so it would be much more secure. I want to encrypt my file, if possible with encryption chosen by user, and make it accessible only if user provide correct username and password.

How would I do this? How do I encrypt file? How can I make it so user can authenticate?

Please be specific, and examples for dummies preferred :)

EDIT: Would that be more secure if I would encrypt every entry in the file using AES? Should I do this and let the database file with no password?

This is how I am accessing a file at this moment:

// May be public so we can display
// content of file from different forms.
public void DisplayFileContent(string filePath)
{
    // Creating an object allowing me connecting to the database.
    OleDbConnection objOleDbConnection = new OleDbConnection();
    // Creating command object.
    objOleDbConnection.ConnectionString =
        "Provider=Microsoft.ACE.OLEDB.12.0;" +
        "Data Source=" + filePath + ";" +
        "Persist Security Info=False;" +
        "Jet OLEDB:Database Password=" + storedAuth.Password + ";";
    OleDbCommand objOleDbCommand = new OleDbCommand();
    objOleDbCommand.Connection = objOleDbConnection;
    objOleDbCommand.CommandText = "Select * FROM PersonalData";

    // Create a data reader.
    OleDbDataReader readPersonalData;

    try
    {
        // Open database connection.
        objOleDbConnection.Open();

        // Associate data reader with the command.
        readPersonalData = objOleDbCommand.ExecuteReader();

        // Counting all entries.
        int countEntries = 0;

        // Clearing the textbox before proceeding.
        txtDisplay.Text = string.Empty;

        if (readPersonalData.HasRows)
        {
            while (readPersonalData.Read())
            {
                // Count all entries read from the reader.
                countEntries++;

                txtDisplay.Text += "=== Entry ID: " + readPersonalData.GetValue(0) + " ===" + Environment.NewLine;
                txtDisplay.Text += "Type: " + readPersonalData.GetValue(1) + Environment.NewLine;
                if (!readPersonalData.IsDBNull(2)) txtDisplay.Text += "URL: " + readPersonalData.GetValue(2) + Environment.NewLine;
                if (!readPersonalData.IsDBNull(3)) txtDisplay.Text += "Software Name: " + readPersonalData.GetValue(3) + Environment.NewLine;
                if (!readPersonalData.IsDBNull(4)) txtDisplay.Text += "Serial Code: " + readPersonalData.GetValue(4) + Environment.NewLine;
                if (!readPersonalData.IsDBNull(5)) txtDisplay.Text += "User Name: " + readPersonalData.GetValue(5) + Environment.NewLine;
                if (!readPersonalData.IsDBNull(6)) txtDisplay.Text += "Password: " + readPersonalData.GetValue(6) + Environment.NewLine;
                txtDisplay.Text += Environment.NewLine;
            }
        }
        else
        {
            txtDisplay.Text = "There is nothing to display! You must add something so I can display something here.";
        }

        // Displaying number of entries in the status bar.
        tsslStatus.Text = "A total of " + countEntries + " entries.";

        // Selecting 0 character to make sure text
        // isn't completly selected.
        txtDisplay.SelectionStart = 0;
    }

My EncryptDecrypt.cs file:

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace Password_Manager
{
    class EncryptDecrypt
    {
        string input, userName, password;

        RijndaelManaged Crypto = new RijndaelManaged();

        public EncryptDecrypt()
        {
        }

        public EncryptDecrypt(string input, string userName, string password)
        {
            this.input = input;
            this.userName = userName;
            this.password = password;
        }

        public string Encrypt(string PlainText, string pass, string usrName)
        {
            string HashAlgorithm = "SHA1"; 
            int PasswordIterations = 2;
            string InitialVector = "OFRna73m*aze01xY";
            int KeySize = 256;

            this.input = PlainText;

            if (string.IsNullOrEmpty(PlainText))
                return "";

            byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
            byte[] SaltValueBytes = Encoding.ASCII.GetBytes(usrName);
            byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText);

            PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(pass, SaltValueBytes, HashAlgorithm, PasswordIterations);

            byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);

            RijndaelManaged SymmetricKey = new RijndaelManaged();

            SymmetricKey.Mode = CipherMode.CBC;

            byte[] CipherTextBytes = null;

            using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes))
            {
                using (MemoryStream MemStream = new MemoryStream())
                {
                    using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
                    {
                        CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
                        CryptoStream.FlushFinalBlock();
                        CipherTextBytes = MemStream.ToArray();
                        MemStream.Close();
                        CryptoStream.Close();
                    }
                }
            }

            SymmetricKey.Clear();
            return Convert.ToBase64String(CipherTextBytes);
        }

        public string Decrypt(string CipherText, string pass, string usrName)
        {
            string HashAlgorithm = "SHA1"; 
            int PasswordIterations = 2;
            string InitialVector = "OFRna73m*aze01xY";
            int KeySize = 256;

             if (string.IsNullOrEmpty(CipherText))
                 return "";

             byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);

             byte[] SaltValueBytes = Encoding.ASCII.GetBytes(usrName);
             byte[] CipherTextBytes = Convert.FromBase64String(CipherText);

             PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(pass, SaltValueBytes, HashAlgorithm, PasswordIterations);

             byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);

             RijndaelManaged SymmetricKey = new RijndaelManaged();

             SymmetricKey.Mode = CipherMode.CBC;

             byte[] PlainTextBytes = new byte[CipherTextBytes.Length];

             int ByteCount = 0;

             using (ICryptoTransform Decryptor = SymmetricKey.CreateDecryptor(KeyBytes, InitialVectorBytes))
             {
                 using (MemoryStream MemStream = new MemoryStream(CipherTextBytes))
                 {

                     using (CryptoStream CryptoStream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read))
                     {
                         ByteCount = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length);
                         MemStream.Close();
                         CryptoStream.Close();
                     }
                 }
             }

             SymmetricKey.Clear();
             return Encoding.UTF8.GetString(PlainTextBytes, 0, ByteCount);
         }
    }
}

Absolutely don't encrypt the data and save the encrypted data in the db you will end up with queries like select field1, field2 from table where field1 = '$WDFV%$:@@{#%SAsdasdh#!fjdkj' and all your fields would have to be text. It reptty much defats the object of using an RDBMS.

An access DB can be password protected and encrypted see this these in instructions are for 2010 but there is also a link to 2007.

However if you are using it as a back end to a winforms gui and you didn't want the user to type it in you would have to store the password somewhere and a determined user would be able to extract it if he/she had the knowledge.

Access is a bad choice if protecting sensitive data from unauthorised users is a priority if it is too late to change at this point in your project then don't use it in future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM