2016-09-30 82 views
0

我们有一些需要共享外部应用程序配置文件的应用程序和服务。外部文件包含一个configSection,其中包含我们要加密的信息。 每个服务和应用程序驻留在它自己的应用程序文件夹中,这就是问题开始升级的地方。 在App.config中,可以使用'configSource'或'file'属性来引用外部文件。 'configSource'无法使用,因为外部配置文件不在应用程序文件夹或应用程序子文件夹中。因此我们必须使用'文件'属性。外部应用程序配置和设置加密

<customSettings file=”path to setting”/> 

为随后的 'customSettings' configSection被定义为:

<configSections> 
    <section name="customSettings" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> 
</configSections> 

我则尝试使用这样的代码来加密configSection:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
ConfigurationSection section = config.GetSection("customSettings"); 

if (!section.SectionInformation.IsProtected) 
{ 
    section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider"); 
    config.Save(); 
} 

因为我使用文件属性(我怀疑)。配置部分在App.config中加密,而外部文件不是。在App.config中加密的只是

<customSettings file=”path to setting”/> 

。这是很没用的。

这意味着个人应用程序和服务无法加密外部配置文件。 然后,我有了一个想法,即将一个小应用程序放置在与外部配置文件相同的目录中。此应用程序的目的是通过使用'configSource'属性来加密外部配置文件。这种方法根本不起作用。什么也没有发生,没有任何加密。

为了进一步研究,我将'customSettings'放​​在App.config中并成功加密了该部分。然后,我将加密的数据复制到外部文件,以测试加密是否可以在外部配置文件中工作。这对'configSource'很好,但在使用'file'属性时引发异常。

抛出异常:

Unrecognized attribute 'configProtectionProvider' 

因为我们必须使用的app.config的“文件”属性我现在有2个问题。

  1. 无法加密外部文件。
  2. 如果手动加密外部文件,我无法使用'文件'属性读取它。
+0

我已经解决了我的第一个问题。 原来,我需要调用: 'section.SectionInformation.ForceSave = true;' 在实际保存配置之前。当使用configSource属性时,外部配置文件现在被加密 –

回答

0

经过大量研究并查看代码NameValueFileSectionHandler的代码后,我意识到该类无法解析file="file path"属性指向的configSection,if加密的外部configSection。不知道这是否是一个错误或不在NameValueFileSectionHandler。也许这里有人可以回答。

但是我最终写了我自己的NameValueFileSectionHandler,它可能会返回NameValueCollection并处理加密的外部配置文件。

public class NameValueFileProtectedSectionHandler : IConfigurationSectionHandler 
{ 
    public object Create(object parent, object configContext, XmlNode section) 
    { 
     object result = parent; 

     XmlNode fileAttribute = section.Attributes.RemoveNamedItem("file"); 

     if (fileAttribute == null && fileAttribute.Value.Length == 0) 
     { 
      return new NameValueSectionHandler().Create(result, null, section); 
     } 

     IConfigErrorInfo configXmlNode = fileAttribute as IConfigErrorInfo; 

     if (configXmlNode == null) 
     { 
      return null; 
     } 

     string directory = Path.GetDirectoryName(configXmlNode.Filename); 
     string absoluteFilePath = Path.GetFullPath(directory + fileAttribute.Value); 

     if (!File.Exists(absoluteFilePath)) 
     { 
      throw new ConfigurationErrorsException(string.Format("external config file: {0} does not exists", absoluteFilePath)); 
     } 

     var configXmlDocument = new ConfigXmlDocument(); 
     try 
     { 
      configXmlDocument.Load(absoluteFilePath); 
     } 
     catch (XmlException e) 
     { 
      throw new ConfigurationErrorsException(e.Message, e, absoluteFilePath, e.LineNumber); 
     } 

     if (section.Name != configXmlDocument.DocumentElement.Name) 
     { 
      throw new ConfigurationErrorsException(string.Format("Section name '{0}' in app.config does not match section name '{1}' in file '{2}'", section.Name, configXmlDocument.DocumentElement.Name, absoluteFilePath)); 
     } 

     var nodeToDecrypt = configXmlDocument.DocumentElement["EncryptedData"]; 

     if (nodeToDecrypt == null) 
     { 
      throw new ConfigurationErrorsException(string.Format("External encrypted file {0} does not contain EncryptedData element", absoluteFilePath)); 
     } 

     var protectionProvider = new DpapiProtectedConfigurationProvider(); 
     var decryptedConfigSection = protectionProvider.Decrypt(nodeToDecrypt); 

     result = new NameValueSectionHandler().Create(result, null, decryptedConfigSection); 

     return result; 
    } 
} 

处理程序被限制为默认配置加密。但我可以想象,可以扩展Create函数以支持app.config文件中定义的自定义提供程序。

1

您可以选择的选项是创建自定义配置节,避免使用appsettings节并依赖自定义配置节。您需要创建自己的处理程序来读取外部文件。当然,您可以指向任何文件,整个文件可能会被混淆,并且不符合XML标准

或者您可以添加设置在指向加密文件并在文件中手动读取的应用程序设置中

+0

感谢您提供的优点。创建了我自己的处理程序。但是这样做,它与NameValueFileSectionHandler是如何内联的。因此,与.NET System.Configuration名称空间中已有的功能具有协同作用。请参阅上面的解决方案 –