拿別人家的app.config讀取securityCryptographyConfiguration的設定來進行加解密

  • 2280
  • 0

拿別人家的app.config讀取securityCryptographyConfiguration的設定來進行加解密

先前遇到了一個怪異的需求,A程式要去load B程式的設定檔,因為用EnterpriseLibary設定的加解密資訊在B程式的config上

image

 

感覺好像很一般般的功能,但是實際做下去才知道.net自身的ConfigurationManager都只能load自己程式的config

既使是用OpenExeConfiguration這個Method指定路徑把config loag進來,其實他還是與App A的config無關,純粹只是load進來

所以我們要動態的把load進來的config加入App A的config內

 

在此之前先提一下load config的方法

剛剛提到的OpenExeConfiguration他有一個多載參數是string,要你填路徑

但是特別注意這邊填的路徑,以現在範例是填B.exe,他會自動幫你變成B.exe.config

所以你如果給的路徑就已經是B.exe.config會變成B.exe.config.config然後就拿不到你想要的東西了,請特小心

那如果我沒有一個.exe給他參考,就可以跟我一樣使用EnterpriseLibary內的FileConfigurationSource來讀取指定的config

 

回到主題,怎把load進來的config加入App A的config內呢

如果你跟我一樣想把load進來的section加入

 
            FileConfigurationSource configFile  = new FileConfigurationSource( filePath );
            Configuration mainConfig            = ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.None );
            ConfigurationSection section        = configFile.GetSection( "securityCryptographyConfiguration" );
            mainConfig.Sections.Add( "securityCryptographyConfiguration", section );

 

你就會得到一個

image

Orz…這也沒錯

 

山不轉路轉,我自己建一個新的section把資料copy過來再加入總行吧

所以我把程式改了一下

FileConfigurationSource configFile  = new FileConfigurationSource( filePath );
Configuration mainConfig            = ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.None );
CryptographySettings section        = (CryptographySettings)configFile.GetSection( "securityCryptographyConfiguration" );
 
CryptographySettings newSection                = new CryptographySettings();
newSection.DefaultHashProviderName             = section.DefaultHashProviderName;
newSection.DefaultSymmetricCryptoProviderName  = section.DefaultSymmetricCryptoProviderName;
 
foreach( HashProviderData data in section.HashProviders )
{ 
    newSection.HashProviders.Add( new HashProviderData( data.Name, data.Type ));
}
 
foreach( SymmetricProviderData data in section.SymmetricCryptoProviders )
{
    newSection.SymmetricCryptoProviders.Add( new SymmetricProviderData( data.Name, data.Type ) );
}
 
mainConfig.Sections.Add( "securityCryptographyConfiguration", newSection );

ok~~就能成功加入,真是太好了

不過離成功還遠的呢!!

 

首先是加入後記的config要Save()一下,所以最後還要加上mainConfig.Save();

否則其他組件要load config時是沒這新的section的

 

再來是雖然加入了加解密的section,但是在使用Cryptographer時他會賞你一個Excption說路徑錯誤

我嘗試了好多地方最後把config檔dump至檔案後發現原來是runtime的設定檔資訊不足

這是B.config的設定內容

image

這是我dump出來的內容

image

 

不用看全貌就知道少了一堆東西,不過在CryptographySettings是沒有這些缺失的資訊的

怎半勒,路不轉人轉.EnterpriseLibary內定義的Section都是繼續自SerializableConfigurationSection

所以可以把整個Section序列,然後再建一個新的反序列回來!!真是太聰明了我

 

/// <summary>
/// 讀取設定檔內的加密區段
/// </summary>
/// <param name="iConfig">原始加密設定區段</param>
private void LoadCryptographySection( CryptographySettings section )
{
    StringBuilder output        = new StringBuilder();
    XmlWriterSettings wSettings = new XmlWriterSettings();
    wSettings.Indent            = true;
 
    using( XmlWriter writer = XmlWriter.Create( output, wSettings ) )
    {
        section.WriteXml( writer );
    }
 
    CryptographySettings newSection = new CryptographySettings();
    XmlReaderSettings rSetting      = new XmlReaderSettings();
    rSetting.CloseInput = true;
 
    StringReader sr = new StringReader( output.ToString() );
    using( XmlReader reader = XmlReader.Create( sr, rSetting ) )
    {
        newSection.ReadXml( reader );
    }
    sr.Close();
 
    //將建立的區段附加至目前runtime的config檔內,一定要save其他地方才會讀到
    //為了不重覆加入加密區段要先移除再加入
    Configuration mainConfig = ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.None );
    mainConfig.Sections.Remove( cryptographyConfigurationName );
    mainConfig.Sections.Add( cryptographyConfigurationName, newSection );
    mainConfig.Save();
}

 

這樣就完成啦!!動態把B.exe.config的加解密區段load到A.exe來運行

而A.exe其實有沒有這個實體的A.exe.config都沒差