Alexanderius
Alexanderius

Reputation: 841

WCF "The primary signature must be encrypted" exception on service response

I am developing a WCF web service and WCF client application which should sign their SOAP messages bodies with certificates.

I have enabled [ServiceContract(ProtectionLevel = ProtectionLevel.Sign)] in my Service interface.

Service Web.config configuration

<system.serviceModel>
    <services>
        <service name="ApsService.Service" behaviorConfiguration="ApsServiceBehaviour">
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="ApsService.IService">
                <identity>
                    <dns value="WcfClient"/>
                </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>

    <protocolMapping>
        <add scheme="http" binding="wsHttpBinding"/>
    </protocolMapping>

    <bindings>
        <wsHttpBinding>
            <binding name="wsHttpEndpointBinding" >
                <security>
                    <message clientCredentialType="Certificate" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>

    <behaviors>
        <serviceBehaviors>
            <behavior name="ApsServiceBehaviour">
                <serviceMetadata httpGetEnabled="true" />
                <serviceCredentials>
                    <clientCertificate>
                        <authentication certificateValidationMode="PeerTrust" />
                        <certificate x509FindType="FindBySubjectName"
                                        findValue="WcfClient" storeName="TrustedPeople" storeLocation="LocalMachine" />

                    </clientCertificate>
                    <serviceCertificate x509FindType="FindBySubjectName"
                                        findValue="WCfServer" storeName="TrustedPeople" storeLocation="LocalMachine" />
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>

    <!--<authentication revocationMode="NoCheck" customCertificateValidatorType="ApsService.ApsCertificatesValidator,ApsService"
                         certificateValidationMode="Custom" />-->
</system.serviceModel>

Client App.config configuration

<system.serviceModel>
    <client>
        <endpoint address="http://localhost/ApsService/Service.svc"
         binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint"
         contract="ApsService.IService" name="WSHttpBinding_IService">
            <identity>
                <dns value="WCfServer" />
            </identity>
        </endpoint>
    </client>

    <bindings>
        <wsHttpBinding>
            <binding name="wsHttpEndpoint">
                <security mode="Message">
                    <message clientCredentialType="Certificate" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>

    <behaviors>
        <endpointBehaviors>
            <behavior>
                <clientCredentials>
                    <clientCertificate findValue="WcfClient" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
                    <serviceCertificate>
                        <authentication certificateValidationMode="PeerTrust" />
                        <defaultCertificate findValue="WCfServer" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
                    </serviceCertificate>
                </clientCredentials>
            </behavior>
        </endpointBehaviors>
    </behaviors>
</system.serviceModel>

The problem is what I am getting MessageSecurityException exception with the text "The primary signature must be encrypted." when the web-service trying to send a response to the client application. I can't find how to fix that problem, may be something missing from my configuration?

Upvotes: 1

Views: 2934

Answers (3)

gen
gen

Reputation: 405

Not sure if this would maybe help anyone, but I recently had this issue. In my case the solution was upgrading the project to a more recent .NET version.

Upvotes: 0

tmanthey
tmanthey

Reputation: 4615

The same error occurs if you forgot to set the protection level.

[ServiceContract(ProtectionLevel = ProtectionLevel.Sign)]

Upvotes: 0

Alexanderius
Alexanderius

Reputation: 841

The problem is solved by custom binding, it disables signature confirmation by:

requireSignatureConfirmation="false"

Client app.config

    <client>
        <endpoint address="http://localhost/ApsService/Service.svc" binding="customBinding" bindingConfiguration="WSHttpBinding_IService"
         contract="ApsService.IService" name="WSHttpBinding_IService">
            <identity>
                <dns value="WcfServer" />
            </identity>
        </endpoint>
    </client>

    <bindings>
        <customBinding>
            <binding name="WSHttpBinding_IService">
                <security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation"
                messageProtectionOrder="SignBeforeEncrypt"
                 messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
                 requireSignatureConfirmation="false" canRenewSecurityContextToken="true">
                    <secureConversationBootstrap defaultAlgorithmSuite="Default"
                     authenticationMode="MutualSslNegotiated" requireDerivedKeys="true"
                     includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
                     requireSignatureConfirmation="false">
                        <localClientSettings detectReplays="true" />
                        <localServiceSettings detectReplays="true" />
                    </secureConversationBootstrap>
                    <localClientSettings detectReplays="true" />
                    <localServiceSettings detectReplays="true" />
                </security>
                <textMessageEncoding />
                <httpTransport />
            </binding>
        </customBinding>
    </bindings>

    <behaviors>
        <endpointBehaviors>
            <behavior>
                <clientCredentials>
                    <clientCertificate findValue="WcfClient" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
                    <serviceCertificate>
                        <authentication certificateValidationMode="PeerTrust" />
                        <defaultCertificate findValue="WCfServer" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
                    </serviceCertificate>
                </clientCredentials>
            </behavior>
        </endpointBehaviors>
    </behaviors>

Upvotes: 2

Related Questions