Search code examples
javaweb-servicesspring-securityspring-wsibm-datapower

Signature verification failed, rsa signature did not verify - IBM Datapower


I've implemented a Web Service client with Spring-WS, and the requirement is to digitally sign the SOAP message and send the request to the IBM Datapower server (DataPower SOA appliance). But the signed SOAP message that the client sends is rejected by the server, returning a SOAP Fault with the following error string: "signature verification failed, RSA signature did not verify".

That target IBM Datapower server is located at customer's side and I'm not authorized to send the SOAP request directly to it in order to debug it properly. So, I've implemented a Web Service server stub also with Spring-WS in order to test the signed SOAP request/response, and both work correctly on my test environment.

The customer confirmed that the keystore files and certificates are correctly configured on both server and client code that I provided to them, but the signature verification error continues on their environment.

But if those same keystore files and certificates are used in SOAP UI to sign exactly the same SOAP message, the request is sent successfully to the Datapower server.

Can somebody please help me with this issue?

Maybe I'm missing something in order to generate the signature correctly with Spring-WS.

Many thanks in advance!

Here is my Spring configuration:

    <context:annotation-config />
    <sws:annotation-driven /> 

    <sws:static-wsdl location="classpath:/META-INF/schema/InfoService.wsdl" />

    <sws:interceptors>
        <sws:payloadRoot namespaceUri="http://www.mycompany.com/getInformation">
            <bean id="payloadValidator" class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
                <property name="schema" value="classpath:/META-INF/schema/getInformation.xsd" />
                <property name="validateRequest" value="true" />
                <property name="validateResponse" value="true" />
            </bean>
        </sws:payloadRoot>
    </sws:interceptors>

    <oxm:jaxb2-marshaller id="marshaller" contextPath="com.mycompany.ws.entity" />

    <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />

    <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
        <constructor-arg ref="messageFactory" />
        <property name="marshaller" ref="marshaller" />
        <property name="unmarshaller" ref="marshaller" />
        <property name="defaultUri" value="http://localhost:8080/dummy-server-stub-ws/InfoService/" />
        <property name="interceptors">
            <list>
                <ref local="wsClientSecurityInterceptor" />
            </list>
        </property>
    </bean>

    <bean id="clientService" class="com.mycompany.service.impl.InformationServiceImpl" scope="prototype">
        <constructor-arg ref="webServiceTemplate" />
    </bean>

    <bean id="clientCrypto" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
        <property name="keyStorePassword" value="${keystore.password}" />
        <property name="keyStoreLocation" value="file:${keystore.location}" />
    </bean>

    <bean id="clientTrustStore" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
        <property name="keyStorePassword" value="${truststore.password}" />
        <property name="keyStoreLocation" value="file:${truststore.location}" />
    </bean>

    <bean id="wsClientSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
        <property name="securementActions" value="Signature" />
        <property name="securementUsername" value="${keystore.alias}" />
        <property name="securementPassword" value="${keystore.password}" />
        <property name="securementSignatureCrypto" ref="clientCrypto" />
        <property name="securementSignatureParts" value="{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body" />
        <property name="securementSignatureKeyIdentifier" value="DirectReference" />
        <property name="securementSignatureAlgorithm" value="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <property name="securementSignatureDigestAlgorithm" value="http://www.w3.org/2000/09/xmldsig#sha1" />

        <!-- Validation config -->  
        <property name="validationSignatureCrypto" ref="clientTrustStore" />
    </bean>

Below is the signed SOAP request:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soapenv:mustUnderstand="1">
      <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="X509-66A2E10F325D0DBA1114508766873871">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</wsse:BinarySecurityToken>
      <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-2">
        <ds:SignedInfo>
          <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
            <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soapenc soapenv xsd xsi"/>
          </ds:CanonicalizationMethod>
          <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
          <ds:Reference URI="#id-1">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soapenc xsd xsi"/>
              </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>FJJvHvb8RcXnlzZWpTgDZkz+CxA=</ds:DigestValue>
          </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>RR9EWs+m1Oo/kAwFWbEdRVtPzN+t7k5MDQF9BTCrIYVL0vbPH7W6B5yuzxFWvlBruL/JEx+3Gxa9iLI6GfmdmHD/NYIc2g01JH8kalbSP/D+F5RkdxNNRHOmLlddUOUfm4DC5QTeF8XMKNDaVEqTBg7hWyd3rFZyNC+nQY+J8jkByuMlqenXwMofxCf1yeP7dg+3U6TbV5dwe3qLUbfWxH1j3mwPhY6PICRFmBOPYRWmN9k57fCqvS5ar9/RYI+BZ6gSdkChx9WsmqI7jmnK/Jk7oBJOMDJSyiOjceKKAc8ZQ6ezo+7dR6UAojiHZEu27822gX70MxUgXW2jJnHCXw==</ds:SignatureValue>
        <ds:KeyInfo Id="KI-66A2E10F325D0DBA1114508766873942">
          <wsse:SecurityTokenReference wsu:Id="STR-66A2E10F325D0DBA1114508766873963">
            <wsse:Reference URI="#X509-66A2E10F325D0DBA1114508766873871" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
          </wsse:SecurityTokenReference>
        </ds:KeyInfo>
      </ds:Signature>
    </wsse:Security>
    <tns:TrackingHdr xmlns:tns="http://www.mycompany.com/ServiceHeader">
      <tns:RequestorInfo>
        <tns:MsgPostTime>2015-12-23 06:18:07.101</tns:MsgPostTime>
        <tns:MessageID>74f5448e4d354ba6918913a01c86d6927e4ed739664c4151</tns:MessageID>
        <tns:CorrelationMessageID>111111</tns:CorrelationMessageID>
      </tns:RequestorInfo>
    </tns:TrackingHdr>
  </soapenv:Header>
  <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-1">
    <ns5:getInformation xmlns:ns5="http://www.mycompany.com/getInformation">
        <ns5:Request>
            <ns5:GetInformationReqGrp>
                <ns5:RequestID>Request-000000</ns5:RequestID>
                <ns5:UserId>User1A</ns5:UserId>
                <ns5:InputElements>13</ns5:InputElements>
                <ns5:CommandRequest>5</ns5:CommandRequest>
                <ns5:Input>
                    <ns5:InputItem>
                      <ns5:Name>AAA_BBB</ns5:Name>
                      <ns5:Value>001</ns5:Value>
                    </ns5:InputItem>
                </ns5:Input>

                ...

            </ns5:GetInformationReqGrp>
        </ns5:Request>
    </ns5:getInformation>
  </soapenv:Body>
</soapenv:Envelope>

Solution

  • After a lot of researches and troubleshooting I managed to solve the issue by adding some Java Virtual Machine Custom Properties on WebSphere 7.

    By default WebSphere ignores all the libraries that the deployed application uses to implement the Web Service. And it overrides them with its own internal Web Service library/engine. In my case the issue involves mainly the SAAJ libraries (SOAP Attachment API for Java).

    I'm answering my own question because it can be useful for somebody to solve similar issues.

    Here is the procedure:

    1. Login to Websphere Console
    2. Click on Servers -> Server Types -> WebSphere application server -> [Server name] -> Java and Process Management -> Process definition -> Java Virtual Machine -> Custom Properties -> New
    3. Add the following five entries and after all restart WebSphere:
                          Name                                              Value
    
        com.ibm.websphere.webservices.DisableIBMJAXWSEngine      true
    
        javax.xml.soap.MessageFactory                            com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
    
        javax.xml.soap.SOAPFactory                               com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl
    
        javax.xml.soap.SOAPConnectionFactory                     com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnectionFactory
    
        javax.xml.soap.MetaFactory                               com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl
    

    That's it.

    Cheers,

    Adianfer