Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly does the enveloped signature transform?

If I want to sign the next XML code with envoloped signature:

<root>
<element>
<child>text node</child>
</element>
</root>

Then the Signature XML code takes place inside the signed XML code, in the way shown below:

<root>
<element>
<child>text node</child>
</element><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature>
</root>

Notice: no line break nor single character is added outside Signature element since that would invalidate the signature.

The XML enveloped signature code includes a <Transform Algorithm> which especifies a modification the code has to suffer, which strictly speaking is done whether in signature or verifying proccess. The <Transform Algorithm> is the next:

<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>

In the W3C website (official documentation) the expression above is compared to the expression below. In both cases the same output have to be produced.

<XPath xmlns:dsig="&dsig;">
   count(ancestor-or-self::dsig:Signature |
   here()/ancestor::dsig:Signature[1]) >
   count(ancestor-or-self::dsig:Signature)</XPath>

Reference: http://www.w3.org/TR/xmldsig-core/#sec-EnvelopedSignature

Before the Transform:

Case 1 (to sign):

<root>
<element>
<child>text node</child>
</element>
</root>

Case 2 (signed):

<root>
<element>
<child>text node</child>
</element><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature>
</root>

After the Transform:

<root>
<element>
<child>text node</child>
</element>
</root>

In both cases the same output is produced, which allow us to verify that the signed data is authentic.

I am still having issue with a server saying my signatures are invalid, can someone please confirm if I am doing the Transform correctly?

Thanks a lot

Regards

like image 852
mikl Avatar asked Jan 10 '23 03:01

mikl


2 Answers

What the Transform does exactly is to erase the whole Signature element with its descendants. A practical example is the next signed data:

<root>
  <element>
    <child>text node</child>
  </element>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature>
</root>

The Transform must produce the next output:

<root>
  <element>
    <child>text node</child>
  </element>

</root>

Notice every character outside Signature is preserved, including every linebreak and space bar. If we represent space bars with colons we have the next view:

<root>
::<element>
::::<child>text node</child>
::</element>
::
</root>

I recommend to visit the next link from where I was able to clear up all my doubts about the issue: http://www.di-mgt.com.au/xmldsig2.html

The best of the link is that it includes a real signed example, from which anyone can reproduce the same DigestValue and confirm the documentations (the practical part is very important in the learning proccess).

like image 180
mikl Avatar answered Jan 18 '23 06:01

mikl


The Transform XPath is recommended but not required. Required is Transform Enveloped Signature.

However Transform Enveloped Signature MUST have the same effect as Transform XPath.

In short,

The Enveloped Signature transform removes the Signature element from the calculation of the signature when the signature is within the content that it is being signed.

That has to already answer your concrete question:

What exactly does the enveloped signature transform?

Even it answers your question it yet might not still leave you any pointers for trouble-shooting your code (which you should provide in your question). As you leave the code out, I can only relate to the XML you've provided. Let's compare this with the answer above:

In your case the content that is being signed is

<getToken>
<item>
<Semilla>001520685466</Semilla>
</item>
</getToken>

And you create the Signature element within it:

<getToken>
<item>
<Semilla>001520685466</Semilla>
</item>
<Signature>...</Signature>
</getToken>

However the Transform XPath requires that the Signature element is within a different XML namespace, here namely &dsig:

<XPath xmlns:dsig="&dsig;">
   count(ancestor-or-self::dsig:Signature |
   here()/ancestor::dsig:Signature[1]) >
   count(ancestor-or-self::dsig:Signature)</XPath>

&dsig; is an XML entity that represents (in that dated specification you refer to) the text "http://www.w3.org/2000/09/xmldsig#". As the Signature element you use is not within that XML namespace, it's not a valid XML Signature and therefore is not addressed by such an XPath expression for XPath transform.

As the required transform MUST match with the recommended XPAth transform, you don't do required things here, as the XPath of the enveloped signature transform T does not match any element(s) in your XML document.

So in short from what you provide this is just a missing XML namespace declaration.

What might make the XPath complicated to you is that it covers the case that a Signature element itself might be signed with another enveloped Signature as well so that from the XML document you want to sign the XPath expression only relates to the enveloped signature of that document and not to the signature as envelope to another (inner) signature within that signature. But also if the Xpath is in context within an envelope that might be a signature as well:

<root>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#" id="envelope">
      ...
      <Signature>
         ...
      </Signature>
  </Signature>
</root>

For such enveloped signatures the XPath has to be able to identify the envelope signature of either <root> or <Signature xmlns="http://www.w3.org/2000/09/xmldsig#" id="envelope"> depending on here() (which is just the context).

like image 36
hakre Avatar answered Jan 18 '23 06:01

hakre