简体   繁体   English

如何在C#中加密/保护MS Access 2007数据库文件?

[英]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. 我有一个程序,可以使用简单的数据库密码访问/添加/删除MS Access 2007文件中的条目。

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? 编辑:如果我将使用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: 我的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);
         }
    }
}

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. 绝对不要加密数据并将加密后的数据保存在数据库中,您将最终遇到查询,例如select field1, field2 from table where field1 = '$WDFV%$:@@{#%SAsdasdh#!fjdkj'字段必须是文本。 It reptty much defats the object of using an RDBMS. 它大大削弱了使用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. 访问DB可以用密码保护和加密的看到这些在说明2010年,但也有一个链接到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. 但是,如果您将其用作winforms gui的后端,并且您不希望用户在其中键入密码,则必须将密码存储在某个地方,并且确定的用户如果拥有密码,则可以提取该密码。知识。

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. 如果保护敏感数据免受未授权用户的侵扰是优先考虑的事情,那么访问是一个坏选择,如果现在在项目中更改时为时已晚,则以后不要使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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