SignatureValue and DigestValue signed and verified with xmlseclibs and csharp

5,211 views
Skip to first unread message

Juan Carlos

unread,
Sep 16, 2012, 8:55:45 AM9/16/12
to xmlse...@googlegroups.com
Hi, I have a problem with signing xml document.

My code to sign is:

    // FIRMAR LA DATA
    $docAFirmar = new DOMDocument();
    $docAFirmar->formatOutput = true;
    $docAFirmar->encoding = 'UTF-8';
    $docAFirmar->loadXML($dataAFirmar);
   
    $objDSig = new XMLSecurityDSig();

    $objDSig->setCanonicalMethod(XMLSecurityDSig::C14N);

    $objDSig->addReference($docAFirmar, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::C14N), array('force_uri' => true));

    objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));

    $sslPath = 'C:\\xampp\\htdocs\\Efactura\\Certificados\\';
    $objKey->passphrase = "mypass";
    $objKey->loadKey($sslPath . PRIVATE_KEY_RSA, TRUE);

    $objDSig->sign($objKey);

    $objDSig->add509Cert(file_get_contents($sslPath . CERT_FILE));
   
    $objDSig->appendSignature($docAFirmar->documentElement);

    $signedDoc = $docAFirmar->saveXML();
   
    I save the $signedDoc data in a file called "doc_signed.xml"
   
    When I send this data to a secured webservice the result is "error in signed data".

I had no idea why they refused my signed doc, so I programmed a simple sign and verify in charp.

When I sign the document with csharp and sign the same document with xmlseclibs, the DigestValue and SignatureValue are differents. Why ? I use the same certificate (public and private key).

When I verify in csharp the signed doc in csharp the result is ok.

When I verify in xmlseclibs the result is wrong.

I am using version xmlseclibs number 1.3.1-dev
   
I can send you the 3 documents (doc before sign, doc signed with xmlseclibs, doc signed with csharp).

Thanks, Juan.

Juan Carlos

unread,
Sep 17, 2012, 9:03:56 PM9/17/12
to xmlse...@googlegroups.com
Hi, I respond to myself:

I need to calculate the same digestValue and SignatureValue as CSharp does.

I found how to calculate the digestValue, and it is so:

$canonicalized = $docAFirmar->documentElement->C14N(false,false);
$digest = base64_encode(pack("H*", sha1($canonicalized)));

But I can't calculate the same signatureValue as CSharp does.

Can you help me:

I tried this ...


            $objDSig = new XMLSecurityDSig();
            $objDSig->setCanonicalMethod(XMLSecurityDSig::C14N);   
            $objDSig->addReference($docAFirmar, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::C14N), array('force_uri' => true));
            $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));

            $sslPath = 'C:\\xampp\\htdocs\\Efactura\\Certificados\\';
            $objKey->loadKey($sslPath . PRIVATE_KEY, TRUE);
            $signedData = $objDSig->signData($objKey, $digest);
           
            echo '<h2>Digest ...</h2><pre>' . htmlspecialchars($digest, ENT_QUOTES) . '</pre>';
            echo '<h2>Signed data ...</h2><pre>' . htmlspecialchars($signedData, ENT_QUOTES) . '</pre>';
            $signedData64 = base64_encode($signedData);
            echo '<h2>Signed data 64 ...</h2><pre>' . htmlspecialchars($signedData64, ENT_QUOTES) . '</pre>';

with no results.
 
Thanks, Juan.

Juan Carlos

unread,
Sep 17, 2012, 10:42:54 PM9/17/12
to xmlse...@googlegroups.com
Again ...

myDigestValue is ...

DKPzvrUxbkiRMQkFrEpqszPlLBU=

The signatureValue calculated with Crypt_RSA is the same as openssl_sign and is the same as xmlseclib is ...

xtHYCCs1J5VphiHvP8jL56LNYaethquIg6dYa7Z1fpINJRx3Bt8Gb3WxG5mk+7m6zNuNbUpRAYO9hpB4OOri3b0FpK7gFLl3oUYWYs4p4e3v3j/eDYtTuu4pvGGAVOse/UEIFDYbMxh8xyHwyvvmMqN34BJvorPOdP8TngjvG6M=

the signatureValue in CSharp is ...

vCUHIjRSg1SHU+PHF8/64n9On4wuLwzlQqnsw23LUO5qHEPKxUsbgEwTmusmgDovvLQfdUvgKjn7Ld6fe6T+x4Hwu4jNfp4s0SL0C258lQifsXadHPfuq07m03RMdz47I/HT+wT7FbiLiKLtOaqMGoV8zIsrsMFqS+OXPsm+QTs=

Why are they differents ?

Thanks, Juan.

Pada

unread,
Sep 18, 2012, 4:34:04 AM9/18/12
to xmlse...@googlegroups.com
Hi Juan,

With XML signing, it is incredibly important to use the correct reference object, otherwise you end up signing the incorrect information.

What you can also do is to decrypt those signatureValues, using the public key, and then you can compare the digest values. The digest values should be the same, otherwise you're signing the wrong XML object/block.

Just take note that when you decrypt the signatureValue, that the unencrypted data won't be just the digest value, but a whole ASN.1 data structure that includes the digest value and signature algorithm.

Lastly, also make sure that your final XML structure is the same and that you're not placing the signature block in the wrong XML element.

I hope this helps somewhat.

Regards,
Chris

Juan Carlos

unread,
Sep 19, 2012, 12:00:51 PM9/19/12
to xmlse...@googlegroups.com
Thanks Chris for your response,

I was trying to find a solution and the only diference I see is the following ...

In CSharp the nodes are putting an space before />

for example the node canonicalizationMethod is ...

<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />

In xmlseclibs in the function setCanonicalMethod you find this ...

$canonNode->setAttribute('Algorithm', $this->canonicalMethod);

This produce the node is (without space) ...

<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>

What can I do in this function to get the canonNode as the csharp node, i.e. add the space

<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />

Thanks, Juan.

Pada

unread,
Sep 19, 2012, 3:22:55 PM9/19/12
to xmlse...@googlegroups.com
Hi Juan,

I'm glad you found the problem.

Technically your CSharp application/webservice is at fault then, because there should be no space before the end of the tag.
Have a look at the C14N example at http://www.w3.org/TR/2001/REC-xml-c14n-20010315#Example-OutsideDoc

They used the input example:
<e3   name = "elem3"   id="elem3"   />
Which resulted in the following canonical form:
<e3 id="elem3" name="elem3"></e3>

The interesting part is that my Java code that I used to sign XML data used in the 3D-Secure environment doesn't add the "</e3>" tag either, instead it just ends it with "/>" and no space before it. so my Java outputs the same as php xmlseclibs:
<e3 id="elem3" name="elem3"/>

So you can probably adjust the php xmlseclibs, but the best way would be to fix the other code that uses the space before the "/>" end tag.

Regards,
Chris

Rob Richards

unread,
Sep 19, 2012, 3:37:20 PM9/19/12
to xmlse...@googlegroups.com, Juan Carlos
The spaces should not be an issue as they all canonicalize down to the same format. Can you possibly send the CSharp code you are using for this as well as the example documents? It works well against services using WSE so am more included to think there is an issue with your code.

Rob
--
You received this message because you are subscribed to the Google Groups "xmlseclibs" group.
To view this discussion on the web visit https://groups.google.com/d/msg/xmlseclibs/-/q8saUBQDe6wJ.
To post to this group, send email to xmlse...@googlegroups.com.
To unsubscribe from this group, send email to xmlseclibs+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/xmlseclibs?hl=en.

Juan Carlos

unread,
Oct 3, 2012, 6:54:50 PM10/3/12
to xmlse...@googlegroups.com, Juan Carlos
Hi, Pada and Rob, I continue with the problem, I send you all the csharp code, I create new certificates to test everything and i continue with the same problem.

Please put all codes in C:\TestCSharp\ and open the file readme.txt

Thanks for your help, Juan.
TestCSharp.rar

Juan Carlos

unread,
Oct 4, 2012, 12:35:12 AM10/4/12
to xmlse...@googlegroups.com, Juan Carlos
I changed the doc to sing and don´t include the xmlns:ds="http://www.w3.org/2000/09/xmldsig#"

so the template ...

const template = '<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><SignatureMethod /></SignedInfo></Signature>';

and the

const prefix = '';

and some changes in xmlseclibs generate the xml in the attached.

Discard previous rar and see only this one.

Thanks Juan.
TestCSharp.rar

Juan Carlos

unread,
Oct 5, 2012, 10:22:47 PM10/5/12
to xmlse...@googlegroups.com, Juan Carlos
One more comment,

when I verify in php the signatureValue generated with xmlseclibs the method fails.

when I verify in php the signatureValue generated with CSharp the method validates well.


Thanks for your help, Juan.

Rob Richards

unread,
Oct 6, 2012, 3:26:31 PM10/6/12
to xmlse...@googlegroups.com, xmlse...@googlegroups.com, Juan Carlos
Hi Juan,

I haven't had a chance to go through all your changes and will be unavailable for next couple weeks so will follow up then. 

Rob
To view this discussion on the web visit https://groups.google.com/d/msg/xmlseclibs/-/TZqJmg5GvUEJ.
Reply all
Reply to author
Forward
0 new messages