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

本文关键字:受保护 添加 连接 字符串 | 更新日期: 2023-09-27 18:15:57

我需要部署一个读取客户数据库的解决方案。我想保护连接字符串来保护密码。关于如何做到这一点,所有的建议至少是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.ConnectionStrings.Add与section.SectionInformation.ProtectSection切换。

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

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

我正在使用这个类

确保你的初始配置是这样的

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