.net – “Unrecognized configuration section” after adding Signature to Config File using SignedXml.ComputeSignature

app-configconfigurationnetxml-signature

I have a Windows Forms application built using the .NET 3.5 Framework which self hosts a WCF service. The service & app function properly on their own.

Concerned about having the address & binding info accessible in the app.config file, I decided to add a digital signature using System.Security.Cryptography.Xml.SignedXml.ComputeSignature. I then added the signature to the the app.config and saved it. This creates a Signature element in the app.config as the final child of the configuration node of the app.config file.

I added a function to check the signature before starting the service. The app properly verifies the signature, but then when trying to start the service, it throws the following nested errors:

  1. The type initializer for 'System.ServiceModel.DiagnosticUtility' threw an exception.

2.Configuration system failed to initialize

3.Unrecognized configuration section Signature.

It doesn't seem to matter where I place the Signature element in app.config. The signature always verifies properly, and the service always bombs griping about the unrecognized configuration section. Commenting out the Signature element in the app.config and the signature check in the code, the service will start again with no issues.

Why does the service throw these errors, and what can I do to resolve them?

Here is the app.config with redacted application names & urls:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="MyApp.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>     
        <binding name="MyAppServicePortBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://myappurl/MyService" binding="basicHttpBinding" bindingConfiguration="MyAppServicePortBinding" contract="MyAppService" name="MyAppServicePort" />
    </client>
    <services>
      <service name="MyApp.MyService" behaviorConfiguration="MyAppServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://mylocalservice:8080/LocalService" />
          </baseAddresses>
        </host>
        <!-- this endpoint is exposed at the base address provided by host -->
        <endpoint address="" binding="wsHttpBinding" contract="MyApp.IServiceInit" bindingNamespace="http://mylocalservice:8080/LocalService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyAppServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
    <applicationSettings>
    <MyApp.My.MySettings>
      <setting name="DefaultEntryType" serializeAs="String">
        <value>M</value>
      </setting>
      <setting name="CardTypes" serializeAs="String">
        <value>1111</value>
      </setting>
      <setting name="Freq" serializeAs="String">
        <value>120000</value>
      </setting>
    </MyApp.My.MySettings>
  </applicationSettings>
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
            <Reference URI="">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                <DigestValue>jJYnz3j6LgxqdcUgvNSGNmJVum4=</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>czpn/uA31kMSoGFk2hi3SCYky6YM6/MjBT3lpMn7wluCjeFIFj0vJJZVI9ueQQn/RglFi8RIfAyov3rDwiS+pP/4b1Yh8KqNOftHMH9pC+CFsMHMQnIoPHyXVrFLpuU6rzjACdUky4zuB7I7Q5AHf1CF8F9PSEgIxiQ4gHgPhJCLujl6wvsMg3rXDHazRQ2Curj94iKUIsKo50X1dJxER1oWOB9g6QgzqsXTOmUkgGOygJrnrn1WQJ0UbWAvHHXIPZdD6jOL24vqhOYm55+b6hlkWdIvEvLBPVMtv2V8oQqxBpWRDh8ovMn4LQdgcFOpa/vG3ISXGp2oRzsCEpaxCQ==</SignatureValue>
    </Signature>
</configuration>

Best Answer

You are missing some essential information to allow signutures to be embedded in the app.config.

From http://www.beefycode.com/post/Managing-AppConfig-Integrity-using-Xml-Digital-Signatures.aspx about adding Signatures to app.config files:

We can't just plop this new element in the app.config and expect the .NET configuration manager to process it without knowing what it is; this will cause failure during application startup. No special tricks here, we simply need to instruct the configuration system to ignore this element by adding the following to the top of the config file.

Start by entering the following in the app.config:

<configSections>
  ...
  <section name="Signature" type="System.Configuration.IgnoreSectionHandler" />  
</configSections>  

View the above link for full app.config and usage example. It should do the job.

Related Topic