Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Validation error when i sign payload using Apigee-Java-WsSec-Signature-2

I am trying to sign a payload using Dino's java callout 2. When i try to validate the same message i signed by invoking validate endpoint using same cert, its failing. I see some special characters in the signed payload . not sure if its causing the issue. anyone ran into similar problem?  Here are my validation and signing configurations.

Sign method: 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<JavaCallout name="Java-WSSEC-Sign-7">
<Properties>
<Property name="source">message.content</Property>
<Property name="expiry">50m</Property>
<Property name="signing-method">rsa-sha1</Property>
<Property name="digest-method">sha1</Property>
<Property name="private-key">{my_private_key}</Property>
<Property name="private-key-password">mypassword</Property>
<Property name="certificate">{my_certificate}</Property>
</Properties>
<ClassName>com.google.apigee.callouts.wssecdsig.Sign</ClassName>
<ResourceURL>java://apigee-wssecdsig-20240426.jar</ResourceURL>
</JavaCallout>

 

Validate: 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<JavaCallout name="Java-WSSEC-Validate-4" continueOnError="false">
<Properties>
<Property name="debug">true</Property>
<Property name="source">message.content</Property>
<Property name="require-expiry">false</Property>
<Property name="digest-method">sha1</Property>
<Property name="signing-method">rsa-sha1</Property>
<Property name="throw-fault-on-invalid">false</Property>
<Property name="certificate">{my_certificate}</Property>
</Properties>
<ClassName>com.google.apigee.callouts.wssecdsig.Validate</ClassName>
<ResourceURL>java://apigee-wssecdsig-20240426.jar</ResourceURL>
</JavaCallout>

 

signature elements looks like below with carriage return escape characters. 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns1="http://ws.example.com/">
<soapenv:Header>
<wssec:Security xmlns:wssec="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-100">
<wsu:Created>2024-11-14T22:20:19Z</wsu:Created>
<wsu:Expires>2024-11-14T23:10:19Z</wsu:Expires>
</wsu:Timestamp>
<wssec: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="ST-101">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</wssec:BinarySecurityToken>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#Body-102">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>lQIvfWFF4/I1s8TG7qYBtcbp3gA=</DigestValue>
</Reference>
<Reference URI="#TS-100">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>aS9BHAuFMsHTvRq736H2PO+E2gQ=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>myrMpAUf+CHYsE1mUxViYb8t9jlZhqP8o0AJC+QUHAY4Z/fZz1HXSwDQOmLFmwTDlf4PW2RVFEPP&#xD;
ePttNJHfmYrKyWjSUxwR2VjgtluqcNfIMQPfOS6cjWD67t7xmwpBT7EdO525lNeU6y/fBmcDH0MM&#xD;
tK9DSyR0hkxXlBowlum0bsm0TWOhV0AN69YI4sQfnBcLusOP6YKJ0NK387CUxN4l8DdUspVML77n&#xD;
puJywTD/CW5J2MM6plWfeZm3TFv2fN2G4/a2TZ6POtSvava9z4niWH7uCFeoo9VbP4FCqLBYRBzK&#xD;
7fgcu2i+GuIv+xZHHhs/KnizP1F6DsFw5zU9XQ==</SignatureValue>
<KeyInfo>
<wssec:SecurityTokenReference>
<wssec:Reference URI="#ST-101" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wssec:SecurityTokenReference>
</KeyInfo>
</Signature>
</wssec:Security>
</soapenv:Header>
<soapenv:Body wsu:Id="Body-102">
<ns1:sumResponse>
<ns1:return>9</ns1:return>
</ns1:sumResponse>
</soapenv:Body>
</soapenv:Envelope>

 

 

Solved Solved
0 8 283
2 ACCEPTED SOLUTIONS


@ranne wrote:

my requirement is to keep following element intact and sign with wsse namespace prefixes. 


<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:ser="http://webservices.cashedge.com/services"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <soapenv:Header>
      <ser:AuthHeader>
        <ser:HomeID>redacted</ser:HomeID>
        <oas:Security>
          <oas:UsernameToken>
            <oas:Username>redacted</oas:Username>
            <oas:Password>redacted</oas:Password>
          </oas:UsernameToken>
        </oas:Security>
      </ser:AuthHeader>
      ...     

The callout will not help you do that.

According to the standard, the Security Header must be a child of the SOAP header.  In your example, you have the Security Header as a child of... some other element. That opens the signed document to signature wrapping attacks. The callout won't allow that.  It's not secure.

You need to use something like this structure:  

 

<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:ser="http://webservices.cashedge.com/services"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <soapenv:Header>
      <ser:AuthHeader>
        <ser:HomeID>redacted</ser:HomeID>
      </ser:AuthHeader>
      <oas:Security>
        <oas:UsernameToken>
          <oas:Username>redacted</oas:Username>
          <oas:Password>redacted</oas:Password>
        </oas:UsernameToken>
      </oas:Security>
      ...     

 

The problem you are seeing has nothing to do with the prefix.  You can use oas, wsse, wssec, dpc, or anything else you please for the prefix. The important matter is the element hierarchy.  It's Envelope/Header/Security.  You cannot use Envelope/Header/AuthHeader/Security .

One could argue that the Signing callout should not accept your document, with that broken hierarchy.  That's a fair point. The Validate callout though, is correctly rejecting the signed document.

If you change your requirements, it will work. 

BTW, the error message from the Validate callout was... not ideal in the case where you had a mis-placed Security element.  I've updated the callout to be more explicit about that now.  You can pull the latest and get that update.

 

View solution in original post

  • There should be no licensing issue. The code is licensed under the Apache License v2.0. Which means you can use it for whatever purpose you desire. 
  • You can modify the code to do as you say.  I advise against it because of the signature wrapping attack risk. But I understand your situation. As far as I can tell the Sign callout will just work - it is the Validate that is rejecting the Security header because of its placement.  So you would need to modify only that.
  • I modified the callout yesterday to be more explicit about checking the placement of the Security header. If you get the latest code it should be easy to modify it to eliminate that check.   In fact I guess I could try making it an option in the callout. 
  • The &#xD is just a carriage return. That is an XML-safe encoding of 0x0D, which is CR.  Any system that correctly processes XML will be able to handle that. more: https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references 

View solution in original post

8 REPLIES 8


@ranne wrote:

When i try to validate the same message i signed by invoking validate endpoint using same cert, its failing.


thanks for the question. I guess you're talking about this callout: https://github.com/DinoChiesa/Apigee-Java-WsSec-Signature-2

You said "it is failing" but didn't specify exactly what you're observing.  Did you see an error message, something that provides some detail behind "it is failing"? 

If the problem is a signature validation error, that can happen if:

  • the payload has been modified in ANY WAY.  If you have "pretty printed" the signed XML, added a newline, or modified anything else, the signature will not vlaidate
  • the certificate you provide at validation time is not the certificate you provided at signing time

You can try specifying "accept-thumbprints" in place of the cert during the Validate step.  Remember, the signed payload includes the cert - that is the BinarySecurityToken element you see in the signed output XML.  The cert is there, you don't need to provide it at Validate time.  You CAN provide it, but it would be redundant. The "thumbprints" option allows you to tell the validate callout to trust a cert with a thumbprint that matches what you provide. so it's a cleaner way of specifying how to validate. 

Try these things and see if it works. 

Does the out-of-the-box demonstration proxy work for you?  If so, what did you change, to try YOUR scenario? did you change the cert + key?  Double check that you're doing that properly.  Did you change the payload?  That will for sure cause a signature validation error.  

EDIT: oops, reading the README again, it says about the certificate for Validation:

This is required (and used) only if the KeyInfo in the signed document does not explicitly provide the Certificate.

So you need to use the "accept-thumbprints" option, for a signed payload in the format you showed. Check the README for more information. I can explain the reasoning for this to you, if you like and if it is not clear.  Let me know.

Thanks for responding back to my question Dino. I was able to go past the test payload signing and validity with my own cert and own proxy. However, i am running into a new problem. my payload i need to sign is in the following format. where oas is name space is declared with wsse xsd. 

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
    <soapenv:Header>
        <ser:AuthHeader>
            <ser:HomeID>redacted</ser:HomeID>
            <oas:Security>
                <oas:UsernameToken>
                    <oas:Username>redacted</oas:Username>
                    <oas:Password>redacted</oas:Password>
                </oas:UsernameToken>
            </oas:Security>
        </ser:AuthHeader>
    </soapenv:Header>
    <soapenv:Body>
        <ser:VerifyAccountInstantly>
            Content redacted
        </ser:VerifyAccountInstantly>
    </soapenv:Body>
</soapenv:Envelope>

When i try to sign it my callout emits following output. i put in validation callout right after signing and it fails at validation step. I assume its due to namespace declaration as oas confusing the signer.  it works fine when i remove oas name space declaration and associated elements from the payload before signing. the output validates fine. 

 

 

 

 

<soapenv:Envelope
    <soapenv:Header>
        <ser:AuthHeader>
            <ser:HomeID>redacted</ser:HomeID>
            <oas:Security soapenv:mustUnderstand="1">
                <oas:UsernameToken>
                    <oas:Username>redacted</oas:Username>
                    <oas:Password>redacted</oas:Password>
                </oas:UsernameToken>
                <wsu:Timestamp wsu:Id="TS-106">
                    <wsu:Created>2024-11-16T18:46:36Z</wsu:Created>
                    <wsu:Expires>2024-11-16T19:36:36Z</wsu:Expires>
                </wsu:Timestamp>
                <oas: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="ST-107">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</oas:BinarySecurityToken>
                <Signature
                    xmlns="http://www.w3.org/2000/09/xmldsig#">
                    <SignedInfo>
                        <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                        <Reference URI="#Body-108">
                            <Transforms>
                                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                            </Transforms>
                            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                            <DigestValue>S73WLcq5Zx//w6wYXBX5Te3jgG0=</DigestValue>
                        </Reference>
                        <Reference URI="#TS-106">
                            <Transforms>
                                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                            </Transforms>
                            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                            <DigestValue>uWFEqmh4iOC2fPoThOoKbas0bi8=</DigestValue>
                        </Reference>
                    </SignedInfo>
                    <SignatureValue>j9cACYkHdukjTG5dBC2NtLMMW9d0mmSR57Sfr1lCagklMqKoockguNMT2OZc3pRh7WkUv6HScc7l&#xD; 5oeM3parW8xaikRYGo+kYlBZ4jFCz0057ufSLCPLIjXxsq9+c7HmQQ7z3bdvLn5KwnZ6JjJbHch2&#xD; rndmAB0EVzI80WSCEKxuYddA63Gwowd0UH8YI438YUwOezbBCsgvOvyMEfr3GBPk1x86789jeXlY&#xD; MDboPCZM3HvpwrtGhUGyH78vddkCJdFQ+p0Cl3gweGMPuGYgggh4ssmD8ulnV459xigiXZjfU25i&#xD; EUllo6WmqEoDTVY95FVCIQVTx9Y8bke6XRKa7w==</SignatureValue>
                    <KeyInfo>
                        <oas:SecurityTokenReference>
                            <oas:Reference URI="#ST-107" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
                        </oas:SecurityTokenReference>
                    </KeyInfo>
                </Signature>
            </oas:Security>
        </ser:AuthHeader>
    </soapenv:Header>
    <soapenv:Body wsu:Id="Body-108">
        Content redacted
    </soapenv:Body>
</soapenv:Envelope>
 
my requirement is to keep following element intact and sign with wsse namespace prefixes. 
 
<ser:AuthHeader>
<ser:HomeID>redacted</ser:HomeID>
<oas:Security>
<oas:UsernameToken>
<oas:Username>redacted</oas:Username>
<oas:Password>redacted</oas:Password>
</oas:UsernameToken>
</oas:Security>
</ser:AuthHeader>

 


@ranne wrote:

my requirement is to keep following element intact and sign with wsse namespace prefixes. 


<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:ser="http://webservices.cashedge.com/services"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <soapenv:Header>
      <ser:AuthHeader>
        <ser:HomeID>redacted</ser:HomeID>
        <oas:Security>
          <oas:UsernameToken>
            <oas:Username>redacted</oas:Username>
            <oas:Password>redacted</oas:Password>
          </oas:UsernameToken>
        </oas:Security>
      </ser:AuthHeader>
      ...     

The callout will not help you do that.

According to the standard, the Security Header must be a child of the SOAP header.  In your example, you have the Security Header as a child of... some other element. That opens the signed document to signature wrapping attacks. The callout won't allow that.  It's not secure.

You need to use something like this structure:  

 

<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:ser="http://webservices.cashedge.com/services"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <soapenv:Header>
      <ser:AuthHeader>
        <ser:HomeID>redacted</ser:HomeID>
      </ser:AuthHeader>
      <oas:Security>
        <oas:UsernameToken>
          <oas:Username>redacted</oas:Username>
          <oas:Password>redacted</oas:Password>
        </oas:UsernameToken>
      </oas:Security>
      ...     

 

The problem you are seeing has nothing to do with the prefix.  You can use oas, wsse, wssec, dpc, or anything else you please for the prefix. The important matter is the element hierarchy.  It's Envelope/Header/Security.  You cannot use Envelope/Header/AuthHeader/Security .

One could argue that the Signing callout should not accept your document, with that broken hierarchy.  That's a fair point. The Validate callout though, is correctly rejecting the signed document.

If you change your requirements, it will work. 

BTW, the error message from the Validate callout was... not ideal in the case where you had a mis-placed Security element.  I've updated the callout to be more explicit about that now.  You can pull the latest and get that update.

 

Much appreciated. Thank you Dino. i see the issue now. Unfortunately my requirements cant be modified as we are trying to migrate from a legacy gateway to apigee where client and the target cant accommodate any changes to the payload. Do you think , If I rewrite the signing library using same bouncy castle where i would ignore existing defintion of known name spaces and just append wsse element under header it would work? i see in your source code you are first checking if there is a known element.  i am hoping to use your code as a reference but rewrite whole thing from scratch. would it have any licensing issues?  

One last question, the signature is generating XML escape characters, &#xD; as below 

<SignatureValue>qye5wAIQ4hj65M3FBsYgKQm6TE66xJMk+pvLk8aGNmOC8R919KLZKJ+Ch3o93i2WghlwlWah2/7S&#xD; LXecwut809kbk0M/ZiaSd+VoH1E9PfE6kN6leQzYZE6TylvHiG5qMtkHV8PTRrnIb3YyIWIjh+Sl&#xD; /OdCfVU49gou/gMIGxw0Zak9QC5HMhTj1ZN4Luy2FyliNGb6VaKYySbSFkQhuoj6X0O7N9m8Gaxf&#xD; qHm+8HdkntKfXR4SjZDAteZTIfC/PZ3Ivv+aHMbnjyGQSFJ6WEMHGrEpa+ENmJKRuYei2lCbAwtq&#xD; CuizOjoZq72iNi9/9zgnglaNmE9bmTVIBkVdcQ==</SignatureValue>

my target server team is complaining it may be also causing issues. i communicated to them it should not be an issue. can you please confirm ?

 

 

  • There should be no licensing issue. The code is licensed under the Apache License v2.0. Which means you can use it for whatever purpose you desire. 
  • You can modify the code to do as you say.  I advise against it because of the signature wrapping attack risk. But I understand your situation. As far as I can tell the Sign callout will just work - it is the Validate that is rejecting the Security header because of its placement.  So you would need to modify only that.
  • I modified the callout yesterday to be more explicit about checking the placement of the Security header. If you get the latest code it should be easy to modify it to eliminate that check.   In fact I guess I could try making it an option in the callout. 
  • The &#xD is just a carriage return. That is an XML-safe encoding of 0x0D, which is CR.  Any system that correctly processes XML will be able to handle that. more: https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references 

Great. Thanks again for your quick response and help !

Hi @ranne 

I introduced a new flag to the signature Validate callout - ignore-security-header-placement. If you set it to true in the policy config, it will allow the structure you described earlier, in which the WS-Sec Security header is not a child of the SOAP header.

Get version 20241120 of the callout for this feature. The configuration looks like this:

 

<JavaCallout name='Java-WSSEC-Validate-Example' continueOnError='true'>
  <Properties>
    <Property name='source'>message.content</Property>
    <Property name='digest-method'>sha1</Property>
    <Property name='signing-method'>rsa-sha1</Property>

    <!-- this property is new -->
    <Property name='ignore-security-header-placement'>true</Property>

    <Property name='accept-thumbprints'>...whatever...</Property>
  </Properties>
  <ClassName>com.google.apigee.callouts.wssecdsig.Validate</ClassName>
  <ResourceURL>java://apigee-wssecdsig-20241120.jar</ResourceURL>
</JavaCallout>

 

Great. Thank you for your help. This worked like charm and it passes validation 🙂