4

我有一个使用 .NET 3.5 Framework 构建的 Windows 窗体应用程序,它自托管 WCF 服务。服务和应用程序自行正常运行。

担心在 app.config 文件中可以访问地址和绑定信息,我决定使用 System.Security.Cryptography.Xml.SignedXml.ComputeSignature 添加数字签名。然后我将签名添加到 app.config 并保存。这会在 app.config 中创建一个 Signature 元素,作为 app.config 文件的配置节点的最终子节点。

我添加了一个功能来在启动服务之前检查签名。该应用程序正确验证了签名,但是当尝试启动服务时,它会引发以下嵌套错误:

  1. 'System.ServiceModel.DiagnosticUtility' 的类型初始化程序引发了异常。

2.配置系统初始化失败

3.无法识别的配置节签名。

我将 Signature 元素放在 app.config 中的哪个位置似乎并不重要。签名总是能正确验证,并且服务总是会抱怨无法识别的配置部分。注释掉 app.config 中的 Signature 元素和代码中的签名检查,服务将再次启动而没有问题。

为什么服务会抛出这些错误,我可以做些什么来解决它们?

这是带有编辑的应用程序名称和 URL 的 app.config:

<?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>
4

1 回答 1

7

您缺少一些允许将签名嵌入到 app.config 中的基本信息。

http://www.beefycode.com/post/Managing-AppConfig-Integrity-using-Xml-Digital-Signatures.aspx关于将签名添加到 app.config 文件:

我们不能只是在 app.config 中添加这个新元素,并期望 .NET 配置管理器在不知道它是什么的情况下处理它;这将导致应用程序启动期间失败。这里没有特别的技巧,我们只需要通过在配置文件的顶部添加以下内容来指示配置系统忽略此元素。

首先在 app.config 中输入以下内容:

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

查看上面的链接以获取完整的 app.config 和使用示例。它应该完成这项工作。

于 2011-10-01T22:03:52.250 回答