如何在使用WiX安装期间加密app.config文件部分?

时间:2008-11-20 21:54:25

标签: .net wix installer app-config dtf

我找到了一个在安装here期间加密web.config的示例,但我的应用程序是一个Windows服务。 aspnetreg_iis方法仅适用于web.config文件。

我知道如何以编程方式加密配置文件,但我不认为我可以使用WiX做到这一点。我错了吗?有什么想法吗?

2 个答案:

答案 0 :(得分:4)

以下是我最终的结果...

我使用WiX和DTF创建了一个托管代码Custom Action来加密配置文件的给定部分:

    public static void EncryptConfig(Session session)
    {

        var configPath = session["APPCONFIGPATH"];
        var sectionToEncrypt = session["SECTIONTOENCRYPT"];

        var fileMap = new ExeConfigurationFileMap();
        fileMap.ExeConfigFilename = configPath;
        var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
        ConfigurationSection section = configuration.GetSection(sectionToEncrypt);

        if (!section.SectionInformation.IsProtected)
        {
            section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
            section.SectionInformation.ForceSave = true;
            configuration.Save(ConfigurationSaveMode.Modified);

        }
    }

我提到这个问题时缺乏理解的部分原因是不知道您可以使用DTF在托管代码中安全地创建自定义操作。 DTF上的文档很少,但是一旦你开始工作,就很棒了。

我发现只有在InstallFinalize之后安排自定义操作时,这才有效。

这是实现它的WiX配置:

<InstallExecuteSequence>
  <Custom Action="EncryptConfigurationFiles" After="InstallFinalize" />
</InstallExecuteSequence>

<Fragment>
    <Binary Id="YourProject.CustomActions.dll" SourceFile="$(var.YourProject.CustomActions.TargetDir)$(var.YourProject.CustomActions.TargetName).CA.dll" />
    <CustomAction Id="EncryptConfigurationFiles" BinaryKey="YourProject.CustomActions.dll" DllEntry="EncryptConfig" Return="check" />
</Fragment>

这些博客/网站帮助我实现了目标,上面的大部分代码都源于它们:

http://geekswithblogs.net/afeng/Default.aspx http://blog.torresdal.net/2008/10/24/WiXAndDTFUsingACustomActionToListAvailableWebSitesOnIIS.aspx http://blogs.msdn.com/jasongin/archive/2008/07/09/votive-project-platform-configurations.aspx

@PITADeveloper ...感谢您的回复。我发现我不需要加载程序集来加密配置文件。

如果你使用它,你应该使用try catch并返回一个ActionResult ......上面是伪代码。

最后,我正在使用DataProtectionConfigurationProvider。对于RSA提供商,我认为还有更多的环节可以跳过。

我希望这有助于某人!

答案 1 :(得分:3)

您应该可以在自定义操作中执行此操作。我发现的问题是为ExeConfigurationFileMap加载程序集会引发异常,但您可以通过向AppDomain添加AssemblyResolve处理程序来处理它。这是一种来自我使用机器加密密钥加密/解密受保护配置部分的富客户端应用程序的hack-up。它可能不是最漂亮的代码,但我希望你能从中得到它的图片。此代码假定您在配置文件中定义了要使用的ProtectionProvider。

//class global
static System.Reflection.Assembly DefiningAssembly;

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);

static System.Reflection.Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
     return DefiningAssembly;
}

然后,您可以像这样加载配置:

DefiningAssembly = System.Reflection.Assembly.LoadFrom("path to defining assembly for config");

//Set the Configuration using an ExeConfigurationFileMap - This works for any .config file.
ExeConfigurationFileMap CfgMap = new ExeConfigurationFileMap();
CfgMap.ExeConfigFilename = "path to config file";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(CfgMap, ConfigurationUserLevel.None);

List<string> DefiningAssemblyTypes = new List<string>();
foreach (System.Type type in DefiningAssembly.GetExportedTypes())
{
     DefiningAssemblyTypes.Add(type.Name);
}

foreach (ConfigurationSection tempSection in config.Sections)
{
     if (DefiningAssemblyTypes.Contains(tempSection.ElementInformation.Type.Name))
     {
          section = tempSection;
          break;
     }
}
ProtectionProviderName = section.SectionInformation.ProtectionProvider.Name;
section.SectionInformation.ProtectSection(ProtectionProviderName);
config.Save(ConfigurationSaveMode.Minimal, true);

我希望这能帮到你,祝你好运。