如何将连接字符串添加为受保护的部分?

时间:2016-11-02 22:29:50

标签: c# sql-server console-application

我需要部署一个读取客户数据库的解决方案。我想保护连接字符串以保护密码。所有建议至少3年,有些是10岁,如何实现这一目标。我遇到了一些错误,例如"此操作在运行时不适用","必须先将配置部分添加到配置层次结构中,然后才能保护它"和" ;无法添加具有已存在的相同名称的ConfigurationSection"。

第一个错误促使我创建一个外部控制台应用程序来调整原始应用程序的配置文件。第二个让我觉得代码的顺序错了。由于原始应用程序的配置不包含连接字符串,因此最终错误令人难以置信。以下是原始应用程序的配置文件。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
</configuration>

以下是试图添加安全连接字符串的控制台应用程序中的代码。

try {
    Uri UriAssemblyFolder = new Uri(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase));

    string appPath = UriAssemblyFolder.LocalPath;

    Configuration config = ConfigurationManager.OpenExeConfiguration(appPath + @"\MyApplication.exe");

    ConnectionStringsSection section = new ConnectionStringsSection();

    section.ConnectionStrings.Add(new ConnectionStringSettings("LocalDB", @"Data Source=localhost;Initial Catalog=master;Persist Security Info=False;User ID=sa;Password=the_password;"));

    section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");

    config.Sections.Add("connectionStrings", section);
    config.Save();
}
catch (Exception ex) {
    printException(ex);
}

您可以假设控制台应用程序与原始应用程序在同一文件夹中运行。要生成第二个错误,可以使用section.SectionInformation.ProtectSection切换section.ConnectionStrings.Add。

我需要添加一个在编译后定义的受保护连接字符串。如果这是不可能的,我还有其他选择吗?将连接字符串文件放在只有原始应用程序可以访问的文件夹中?

1 个答案:

答案 0 :(得分:-1)

我正在使用这个课程

  

确保您的初始配置就是那样

<appSettings>
    <add key="connectionString" value="" />
</appSettings>
public class SecureConfig
{
    private Configuration applicationConfiguration = null;

    public SecureConfig()
    {
        applicationConfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    }

    public SecureConfig(Configuration config)
    {
        applicationConfiguration = config;
    }

    private static string EncryptString(string InputText, string Password)
    {
        RijndaelManaged RijndaelCipher = new RijndaelManaged();
        byte[] PlainText = System.Text.Encoding.Unicode.GetBytes(InputText);
        byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
        PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
        ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(PlainText, 0, PlainText.Length);
        cryptoStream.FlushFinalBlock();
        byte[] CipherBytes = memoryStream.ToArray();
        memoryStream.Close();
        cryptoStream.Close();
        string EncryptedData = Convert.ToBase64String(CipherBytes);
        return EncryptedData;
    }

    private static string DecryptString(string InputText, string Password)
    {
        RijndaelManaged RijndaelCipher = new RijndaelManaged();
        byte[] EncryptedData = Convert.FromBase64String(InputText);
        byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
        PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
        ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
        MemoryStream memoryStream = new MemoryStream(EncryptedData);
        CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
        byte[] PlainText = new byte[EncryptedData.Length];
        int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length);
        memoryStream.Close();
        cryptoStream.Close();
        string DecryptedData = Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);
        return DecryptedData;
    }

    public string GetConnectionString(string password)
    {
        return DecryptString(applicationConfiguration.AppSettings.Settings["connectionString"].Value.Trim().ToString(), password);
    }

    public bool IsEmpty()
    {
        return String.IsNullOrEmpty(applicationConfiguration.AppSettings.Settings["connectionString"].Value.Trim().ToString());
    }

    public void SetConnectionString(String sConnectionString, string password)
    {
        applicationConfiguration.AppSettings.Settings["connectionString"].Value = EncryptString(sConnectionString, password);
        applicationConfiguration.Save(ConfigurationSaveMode.Modified);
        ProtectSection("appSettings");
    }

    private void ProtectSection(String sSectionName)
    {
        ConfigurationSection section = applicationConfiguration.GetSection(sSectionName);
        if (section != null)
        {
            if (!section.IsReadOnly())
            {
                section.SectionInformation.ForceSave = true;
                applicationConfiguration.Save(ConfigurationSaveMode.Modified);
            }
        }
    }

}