Search code examples
springsoap-clientspring-ws

Spring-WS Decrypt body part


so I'm communicating with a service via soap. The repose body looks as follows.

<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
        <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"/>
        <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
          <wsse:SecurityTokenReference>
            <wsse:KeyIdentifier 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#X509SubjectKeyIdentifier">plU1gwH/05daoxwRJYvuAViKUp4=</wsse:KeyIdentifier>
          </wsse:SecurityTokenReference>
        </dsig:KeyInfo>
        <xenc:CipherData xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
          <xenc:CipherValue>J/AQ6BnIAbTgrXYkRAg7mB1sKEQcroAvc/5Gy1a60oN+nxISGjS+W/sdbX9XAG8paAb+Zb6WoOyxw+9ZN9SFpq3TpDnjO/F/6DDisVOG5i65KnC3bDG1Y2tpRsGZzKvzPGB3O2mmnBGSfVb5FNDZoeBLQqlHf8iKc8GPQlTuAOWhEKStU20RXN9FjmSumiYxa0EUitFoGicVHg2ym5EEuVb10yGbkMPGcqGb2hZc/4pAJC8RORZmyXV2cZFin7ngfneD6uz7y5i3RPVvBNtN4kET75AoLJd3vJUXOevSXojiSoYb89adjRtrs2lVtthX+yh7x1ddwSeJ7+Ah5kW6JA==</xenc:CipherValue>
        </xenc:CipherData>
        <xenc:ReferenceList>
          <xenc:DataReference URI="#G0x7f16e7565138-46D"/>
        </xenc:ReferenceList>
      </xenc:EncryptedKey> 
...
<soapenv:Body wsu:Id="Body-ab9464bb-3e1e-4d4f-94a6-9f75b7e4f6bd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <c:validateResponse xmlns:a="http://ebs.health.ontario.ca/" xmlns:b="http://idp.ebs.health.ontario.ca/" xmlns:c="http://hcv.health.ontario.ca/">
      <xenc:EncryptedData Id="G0x7f16e7565138-46D" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
        <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
        <xenc:CipherData>
          <xenc:CipherValue>IL3224+2hgeCS18/fT4aGSDawPFfz5d4WX2428mLH7K+fKuWSgY0Aq/Qn6qCaNdX1ZvlIpVgOqHIU7ggnDlKIZEVVL50ex4czoBN4Ii9w+lu1JMFb/m3ijQbUAV3SfjqxPmVlRklIjjZXSIyd9/TT7V35vKL6Md1dHxbrjm9jtcd1jhzKcG7pLQjg94eJsAi4gxMiMELXU2IrzQRym8dvjw57cSIU6SdII5RORH5YyP6/Qivx5NOEJijjw+fGAuGBrbSqhjOW0BlidW/Zu/i0d6Qwx0FmCwvjlJ0Su5wSofF6rY/X6A3iaQ1AB7RgUVhQOLLCu0/q7mrJHbX0pcPfhw1pv69RoIz7kcVNLZhw9vidUyAaPnbwUKahS2kk6jy3brNM6NpS8Mb906ioihqRd+3utyGqs7pCtTW7iM6pYyiu27GNCt05hBiDXm1bQUqIAUv3q1ROSVxEgLAdD6AMBmJl9Rq0G/dHv3MoYd9aTLFvK+QCaXBovib1ZcdqQJTZf2twAv2Jesm+eyKqwQO/NpOkmUxE/OWEfY5vUkRBMOgg5mBNV1r/sMNOuEs9SWIGCOMZLRh61WgVCgfaLlByYTAKdA1rIohxVqbQti5onZSgbkKU0I3zSTJGPGdirvUSRc9AM6dcetK3dM03/3XCg0LJRqOgsdseK+BDjsu3yDgyWpHfUCXZlObt66BPXi7J5VlBPI4fXM47TK9TtOL7D82yLt0hbSk37iCrbkZ0XIGunJ9i+XJ2mI5B8+yVEfEsV4QxcA2QX+BVyMMeLPooBoCzZLTuSXDX2wutO+a+90FeD4G8P185KC/X1ylpTywuGPtpx/7NIqh+yozA5RRkTWDxnR4YxtIt4FESyW9yuj9J2Mjz6U2E0FViGuXy2b5oFEnpia9PrUpNspQziQ1FONRHF66KmARSqfyg22mhun/szLUxoL3QFbpsJ+GLtAN0F4jegzEP2c+DBipvJrP8Zlc27gGA70R6icH5KqhkNCOT69l06gsjeU1jVZxoVFx</xenc:CipherValue>
        </xenc:CipherData>
      </xenc:EncryptedData>
    </c:validateResponse>
  </soapenv:Body> 

note that validateResponse has encrypted data. This was encrypted using the public key from the request. When I try an do webServiceTemplate.marshalSendAndReceive, I get the JAXBElement is always null.

Below is my security interceptor

@Bean
    @Throws(Exception::class)
    fun wss4jSecurityInterceptor(): Wss4jSecurityInterceptor {
        val securityInterceptor = Wss4jSecurityInterceptor()


        // set security actions: Timestamp Signature SAMLTokenSigned SAMLTokenUnsigned
        securityInterceptor.setSecurementActions("Timestamp Signature UsernameToken")
        //securityInterceptor.setValidationCallbackHandler(securityCallbackHandler())
        securityInterceptor.setSecurementUsername("USERNAME")
        securityInterceptor.setSecurementPassword("PASSWORD")
        securityInterceptor.setSecurementPasswordType(WSConstants.PW_TEXT)

        // sign the request
        securityInterceptor.setSecurementUsername(signingCertName)
        securityInterceptor.setSecurementPassword(signingCertPassword)
        securityInterceptor.setSecurementTimeToLive(5000)
        securityInterceptor.setTimestampStrict(false)
        securityInterceptor.setSecurementSignatureCrypto(myCrypto())
        securityInterceptor.setSecurementSignatureParts(
                "{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;" +
                "{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;" +
                "{Element}{http://ebs.health.ontario.ca/}EBS;" +
                "{Element}{http://idp.ebs.health.ontario.ca/}IDP;"
        )
        securityInterceptor.setSecurementSignatureDigestAlgorithm("http://www.w3.org/2000/09/xmldsig#sha1")
        securityInterceptor.setSecurementSignatureAlgorithm("http://www.w3.org/2000/09/xmldsig#rsa-sha1")
        securityInterceptor.setSecurementSignatureKeyIdentifier("DirectReference")
        securityInterceptor.setSecurementMustUnderstand(true)

        val keyStoreCallbackHandler = KeyStoreCallbackHandler()
        keyStoreCallbackHandler.setPrivateKeyPassword("PASSWORD")
        securityInterceptor.setValidationDecryptionCrypto(myCrypto())
        securityInterceptor.setValidationCallbackHandler(keyStoreCallbackHandler)
        securityInterceptor.setSecurementEncryptionParts("{Element}{http://hcv.health.ontario.ca/}validateResponse;")
        securityInterceptor.setSecurementEncryptionCrypto(myCrypto())
        securityInterceptor.setValidationActions("Encrypt")
        securityInterceptor.setValidationActor("USERNAME")
        securityInterceptor.setValidateRequest(false)
        securityInterceptor.setValidateResponse(false)

        securityInterceptor.afterPropertiesSet()
        return securityInterceptor
    } 

EDIT: Updated the soap request with part of the header

Reading the specs for the server I'm coummunicating with,

If any response data is specified to be enc rypted, by the specific web service technical specification, the data will be encrypted using, at least, the AES128- CBC symmetric encryption algorithm with the public key belonging to the signer of the initial SOAP request. The encryption algorithm may be increased based on the specific web service technical specification.

I'm not sure how to be able to do that


Solution

  • So I figured it out.

    It was skipping the validation

    securityInterceptor.setValidateRequest(false)
    securityInterceptor.setValidateResponse(false)
    

    needed to be removed