Encrypt Web.Config including External appSettings and ConnectionStrings Files.

 Before two days from now, the project that I'm working one required a web.config  encryption. I know that encrypting web.config nodes is very easy with aspnet_regiis.exe! but i found me self in a big google jungle!.

the first think was because my web.config uses appsetings and conectionstrings as an extarnal xml file! Extarnal files can not be encrypted with aspnet_regiis command; you can encrypt the node element in the web.config xml but not the file it self. so that was a big challange to be done.

the only way i found to pass this is to read the extarnal files and inject them inside the web.config. but here is the next challange. the Xmlns made my day horrible. let us start from teh begining.

i used to delete the existing node element (appseting and connectionstrings ) from my web config to recreate them again;

                XmlDocument webconfig = new XmlDocument();
                webconfig.Load(webConfig);
                RemoveNodes(webconfig);//removes appseting and connectionstirng nodes from web.config
                webconfig.Save(webConfig);

 

private static void RemoveNodes(XmlDocument webconfig)
        {
            XmlNodeList node = webconfig.GetElementsByTagName("appSettings");
            if (node != null)
            {
                for (int i = node.Count; i > 0; i--)
                {
                    webconfig.DocumentElement.RemoveChild(node[i - 1]);
                }
            }
            node = webconfig.GetElementsByTagName("connectionStrings");
            if (node != null)
            {
                for (int i = node.Count; i > 0; i--)
                {
                    webconfig.DocumentElement.RemoveChild(node[i - 1]);
                }
                node = null;
            }
        }

every thing goes fine until now, after that i create the elements again this way 

                XmlElement appSetElem = webconfig.CreateElement("appSettings", "http://schemas.microsoft.com/.NetConfiguration/v2.0");
                XmlElement connElem = webconfig.CreateElement("connectionStrings", "http://schemas.microsoft.com/.NetConfiguration/v2.0");

the two element are created. here i used the namespceuri XMLNS as  "http://schemas.microsoft.com/.NetConfiguration/v2.0" which is the same like the root node "configuration", there for when i create these elements the namespace is nothing and the element looks like this <appSettings></appSettings> and the same for connetionStrings. after that i read the appsettings xml from the extarnal file and inject it as appSetting innerXml.

                XmlDocument appSetting = new XmlDocument();
                appSetting.Load(appSettings);
                XmlNodeList appElement = appSetting.GetElementsByTagName("appSettings");
               appSetElem.InnerXml = appElement[0].InnerXml;

              webconfig.DocumentElement.AppendChild(appSetElem);
              webconfig.Save(webConfig);

But here when i try to save the web.config and because of Serialization i found out that each injected key have got an empty xmlns which is not needed!.

<add key="xyz" value="what ever" xmlns="" />

to do the encryption xmlns's must me deleted from the keys. i tried many  many ways, but nothing changed. at the end i found a way to remove xmlns from child elements!

Because the both elements are newly created serialization is needed. I thought to use already created nodes to avoid that, there for i removed this line

RemoveNodes(webconfig);//removes appseting and connectionstirng nodes from web.config

and replace it with these lines;

                XmlNodeList appSettingsnode = webconfig.GetElementsByTagName("appSettings");
                appSettingsnode[0].RemoveAll();

these lines read the web.config and finds appSettings element and removes all attributes and innerxml from the element. after that i injected the external xml file inside appsetings element and save the doc;

                XmlDocument appSetting = new XmlDocument();
                appSetting.Load(appSettings);
                XmlNodeList appElement = appSetting.GetElementsByTagName("appSettings");
                appSettingsnode[0].InnerXml = appElement[0].InnerXml;

and that was the trick. XMLNS free element and innerxml. 

here is the full code;

public bool marriageAll(string webConfig, string appSettings, string connectionSettings, bool deleteOldies)
        {
            try
            {

                XmlDocument webconfig = new XmlDocument();
                webconfig.Load(webConfig);
               
                XmlNodeList appSettingsnode = webconfig.GetElementsByTagName("appSettings");
                appSettingsnode[0].RemoveAll();
              
                XmlNodeList ConnectionSetnode = webconfig.GetElementsByTagName("connectionStrings");
                ConnectionSetnode[0].RemoveAll();

                XmlDocument appSetting = new XmlDocument();
                appSetting.Load(appSettings);
                XmlNodeList appElement = appSetting.GetElementsByTagName("appSettings");

                appSettingsnode[0].InnerXml = appElement[0].InnerXml;

                XmlDocument connSetting = new XmlDocument();
                connSetting.Load(connectionSettings);
                XmlNodeList connElement = connSetting.GetElementsByTagName("connectionStrings");
                ConnectionSetnode[0].InnerXml = connElement[0].InnerXml;
        
                webconfig.Save(webConfig);

                if (deleteOldies)
                {
                    DeleteFiles(appSettings, connectionSettings);
                }

            }
            catch (Exception ex)
            {
                return false;
                throw ex;
            }
            return true;

        }

        private static void DeleteFiles(string appSettings, string connectionSettings)
        {
            File.Delete(appSettings);
            File.Delete(connectionSettings);
        }
    }

after all that you can encrypt the file by using aspnet_regiis -pe "appSetings" -app "/website"

 i spent 2 days to solve it; i hope you can solve it more faster.

you may down the full project from here (vs 2008, .net 3.5 sp1).

hope this helps

 

1 Comment

Comments have been disabled for this content.