65.9K
CodeProject 正在变化。 阅读更多。
Home

加密 Windows 应用程序连接字符串

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.65/5 (11投票s)

2007年4月25日

CPOL

3分钟阅读

viewsIcon

133051

downloadIcon

6071

本文展示了一种加密 Windows 应用程序连接字符串的简单方法

引言

通过本文介绍的几个简单步骤,可以轻松地为 Windows 应用程序加密连接字符串。

背景

为了保护 Windows 应用程序的连接字符串,我查阅了 .NET Framework 开发人员指南。其中提到“ASP.NET 2.0 提供了一项名为‘受保护的配置’的新功能,允许您加密配置文件中的敏感信息。尽管此功能主要为 ASP.NET 设计,但也可以用于加密 Windows 应用程序中的配置文件节。”

按照此指南,我在我的计算机上的应用程序中成功地加密和解密了我的连接字符串。但是,在分发应用程序后,出现了以下错误:“使用提供程序‘MyUserDataProtectionConfigurationProvider’解密失败。提供程序的错误消息:密钥无效,无法在指定状态下使用。(异常来自 HRESULT:0x8009000B)”,这在“如何:使用 DPAPI 加密 ASP.NET 2.0 中的配置节”一文中有所描述。

此错误发生的原因是,默认情况下用于解密字符串的密钥是特定于计算机的。为了解决这个问题,Hameer Saleem 撰写了一篇出色的文章“在 Windows 应用程序中实现受保护的配置”,该文章解释了如何通过 Windows 安装程序加密分布式应用程序中的应用程序设置。

本文基于 Hameer Saleem 的文章,与其非常相似,但省略了一两个步骤,并侧重于连接字符串。

Using the Code

  1. 连接字符串 存储在 应用程序设置
  2. 添加安装程序类并重写 Install 方法
  3. 添加一个 Setup Project,其中包含一个自定义操作,该操作包含项目的首要输出
  4. 安装应用程序

1. 将连接字符串存储在应用程序设置中

创建一个 新项目,然后在 项目设计器设置页面 中,为连接字符串创建一个新的 应用程序设置。在此示例中,项目名为“MyConnectionString”,连接字符串应用程序设置为“ConnectionString”。

如何:使用设计器创建应用程序设置

Screenshot - Settings.jpg

通过创建新的应用程序设置,项目设计器 将创建一个设置类,该类通过 Properties 命名空间向项目公开连接字符串,从而方便从代码中访问连接字符串。应用程序设置使用 Properties.Settings.Default 对象进行访问,如下所示:

string databaseConnectionString = Properties.Settings.Default.ConnectionString;

有关详细信息,请参阅“在 C# 中使用设置

项目设计器还将创建一个 应用程序配置文件,名为 *app.exe.config*(其中 app 是主可执行文件的名称),其中将包含连接字符串的应用程序设置:<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> </configSections> <connectionStrings> <add name="MyConnectionString.Properties.Settings.ConnectionString" connectionString="Data Source=(local)\SQLExpress;Initial Catalog=AdventureWorks;Integrated Security=True" /> </connectionStrings> </configuration>

2. 添加安装程序类并重写 Install 方法

要保护连接字符串,请添加 System.Configuration 引用,向项目添加一个 安装程序类,然后在此类中重写 Install 方法,并使用以下代码:

using System.Configuration;
public override void Install(IDictionary stateSaver) 
{ 
    base.Install(stateSaver);

    //Opens the specified client configuration file as a Configuration object 
    Configuration config = ConfigurationManager.OpenExeConfiguration( 
        //Gets the source directory of the installation from the default 
        //context parameters 
        Context.Parameters["assemblypath"]); 

    // Get the connectionStrings section. 
    ConfigurationSection section = config.GetSection("connectionStrings"); 

    //Ensures that the section is not already protected 
    if (!section.SectionInformation.IsProtected) 
    { 
        //Uses the Windows Data Protection API (DPAPI) to encrypt the 
        //configuration section using a machine-specific secret key 
        section.SectionInformation.ProtectSection(
            "DataProtectionConfigurationProvider"); 
        config.Save(); 
    }
}

如何:添加新项目项

使用 System.Configuration.ConfigurationSection,可以从应用程序配置文件中获取应用程序设置节,并使用 Windows 数据保护 API 或 RSA 加密算法对其进行加密。在此示例中,我获取应用程序配置文件的“connectionStrings”节,并使用 Windows 数据保护 API 进行加密。

有关更多信息,请参阅 保护连接字符串

3. 添加 Setup Project,其中包含一个自定义操作,该操作包含项目的首要输出

然后,需要向解决方案添加一个 Setup 项目,其中包含项目的首要输出。 Screenshot - AddPrimaryOutput.jpg

选择 自定义操作编辑器,并添加一个 自定义操作

Screenshot - CustomActionsEditor.jpg Screenshot - AddCustomAction.jpg

然后选择应用程序的首要输出。在此例中,它是 MyConnectionString 的首要输出。 Screenshot - PrimaryOutput.jpg

4. 安装应用程序

就是这样。现在,当应用程序编译并安装后,应用程序配置文件将被保护,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    <connectionStrings configProtectionProvider=
        "DataProtectionConfigurationProvider">
       <EncryptedData>
          <CipherData>
              <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA4UsuQ1ImfEC
              1YDl6Y5urvwQAAAACAAAAAAADZgAAqAAAABAAAACtumZfWRxJZ76othC3F0a
              UAAAAAASAAACgAAAAEAAAAOE/Mbi8KBK6v9mA0CaH6m/AAQAA7HWRf5RjQ5q
              jknQ+wjFQtIyrXQ7N3Pqtc9f6WiJXU8hmOKo2lC4fW/y+7ttDpx4Wse/
              Ez7b2vzu7B4KcEF1rr+ic/nMZRcHUsvG6E/DVEIaWOvSe0IcVOdqj
              UD6iBySwHdrY2QT50HuHI/MGR60vP84V+VwQd0IPmMp5kBOFawgCfTCq
              61ZJebZ9+Ng4AVZ4jpAgNTp7DVZXz3IVpoLPHPnwbvkbvAI/HCX2MYlGj
              hTzGyzSViTvPCMeMvvaz5Jdfj2Z3JeRcVQSgh3xjl8amcR0M25eCHXKyc
              f6YLUXFRs4LgYTaYqIoRDya1WpAgbv0pQ5mZAa1SqUQ5AvCyuPR+1XT9m
              DZTlhJALdnIJWxRiRJ38kzRJvenGjPrvKAZCISSHYC0olZha34ijQ/RgMW
              96kmWRw0Kr2kiZEeUdhUWCQ6Qaa3EwKjF3b9u0WrHw1UdE6ZRL62W6p6PkE
              +GmGoX1s3f73U7LPHXdKXsWapdTpSk51pTxGDmuQswHiDpiWeEeI1gO3pmw
              an4rpSjlAhjxi/OIu7Bm98VOa8SvmP1oTCXN9XefZWekZ86z7+7DLFLV2H6/
              KTK9LqHAew8whpRQAAAD3As0X5IF2d18
              SdVKCYWyO+o/l3A==</CipherValue>
          <;CipherValue>;AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA4U... <;/CipherValue>;
         </CipherData>
       </EncryptedData>
    </connectionStrings>
</configuration>

运行时,程序将解密受保护的数据并返回正确的字符串。

Console.WriteLine(Properties.Settings.Default.ConnectionString);

Screenshot - Output.jpg

© . All rights reserved.