Как зашифровать / защитить файл базы данных MS Access 2007 в C #? - PullRequest
2 голосов
/ 01 декабря 2011

У меня есть программа, которая позволяет мне получать доступ / добавлять / удалять записи из файла MS Access 2007, используя простой пароль базы данных.

Но моя цель - изменить мой файл, чтобы он был намного более безопасным. Я хочу зашифровать свой файл, если это возможно, с помощью выбранного пользователем шифрования и сделать его доступным, только если пользователь предоставит правильное имя пользователя и пароль.

Как бы я это сделал? Как мне зашифровать файл? Как я могу сделать так, чтобы пользователь мог аутентифицироваться?

Пожалуйста, будьте конкретны, и предпочтительны примеры для чайников:)

РЕДАКТИРОВАТЬ: Это было бы более безопасно, если бы я зашифровал каждую запись в файле, используя AES? Должен ли я сделать это и позволить файлу базы данных без пароля?

Вот так я сейчас получаю доступ к файлу:

// 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:

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);
         }
    }
}

1 Ответ

1 голос
/ 01 декабря 2011

Абсолютно не шифруйте данные и сохраняйте зашифрованные данные в БД, в результате вы получите запросы типа select field1, field2 from table where field1 = '$WDFV%$:@@{#%SAsdasdh#!fjdkj', и все ваши поля должны быть текстовыми.Это значительно опровергает объект использования СУБД.

БД доступа может быть защищена паролем и зашифрована. См. это эти инструкции относятся к 2010 году, но есть также ссылка на 2007 год.

Однако, если вы используете его как бэкэнд для графического интерфейса winforms и не хотите, чтобы пользователь вводил его, вам придется где-то хранить пароль, и определенный пользователь сможет извлечь его, еслиу него / нее были знания.

Доступ - это плохой выбор, если защита конфиденциальных данных от неавторизованных пользователей является приоритетной задачей, если уже слишком поздно вносить изменения в данный момент в вашем проекте, тогда не используйте его в будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...