Help Required : Generating Digest Values and Signature

441 views
Skip to first unread message

Tejas Trivedi

unread,
Nov 21, 2014, 9:43:48 AM11/21/14
to xmlse...@googlegroups.com
Hi Guys,

I am trying below from last 1 month. I am not able to get it done. Please help me.

I have below XML. How can I generate Digest values for below 2 references and signature using PHP?

Below is the entire XML. I generates Digest Value of below 2 references with below code. Let me know whether it is right or wrong?


$digest1 = base64_encode(pack("H*", sha1("")));

$digest2 = base64_encode(pack("H*", sha1("cid:AddOrder"))); 

But I think , this is not right. So can someone please give hint what input should be there to generate Digest value and also the process if it is long?

Also, Can you please suggest how can I generate signature value as well?

Thanks,

Tejas Trivedi.
test.xml

Rob Richards

unread,
Nov 21, 2014, 2:35:55 PM11/21/14
to xmlse...@googlegroups.com
Looking at your XML you provided your first digest is on URI="" with an
xpath transformation of:
not(ancestor-or-self::node()[@soap:actor="urn:oasis:names:tc:ebxml-msg:action:nextMSH"]
|
ancestor-or-self::node()[@soap:actor="http://schemas.xmlsoap.org/soap/actor/next"])

That means it is take the entire document (it does not include the
signature node since its an enveloped signature) and running that xpath
against it. You then canonicalize it to produce the data that you need
to hash.
You can then just do: base64_encode(sha1($data, TRUE)

The second digest however is a bit more difficult. It looks like that is
SOAP with attachments and you are not including the content referenced
by cid:AddOrder
Whatever that data refers to you would run the same digest code as above.

Rob


Tejas Trivedi

unread,
Nov 22, 2014, 2:57:50 AM11/22/14
to xmlse...@googlegroups.com
Hi Rob,

Thanks for your reply.

So what i understood is, for the first digest , need to take entire ebXML (excluding ds:Signature element) from the xml. Here is the code , correct me if i am wrong.

The below $xml contains the XML excluding ds:Signature element.

$doc = new DOMDocument();
$doc->loadXML($xml);

$data = $doc->C14N();

$digest1 = base64_encode(sha1($data, TRUE);

And for digest2, need to take a payload of Add Order (entire XML) and need to perform same as above.

Please confirm.

Thanks Again,

Tejas Trivedi

unread,
Nov 24, 2014, 9:57:30 AM11/24/14
to xmlse...@googlegroups.com
Hi Rob,

Thanks for your reply.


Please find attached entire post values I am passing.

Now let me tell you the Process of generating Digest1, Digest2 and Signature. Let me know if i am doing wrong.

From the first ebXML part , removing entire <ds:signature> element, then cannonicalize it and generating digest 1.

$xml is first xml without ds:signature element.


$doc = new DOMDocument();
$doc->loadXML($xml);

$data = $doc->C14N();

$digest1 = base64_encode(sha1($data, TRUE);

Now for digest 2, same process but $xml will be next xml which is (btw:AddOrder).

Can you please suggest anything wrong for creating digest, or anything with request also?

Thanks in advance.

Tejas Trivedi.
xml.xml

Rob Richards

unread,
Nov 24, 2014, 3:41:02 PM11/24/14
to xmlse...@googlegroups.com
For the first signature you need to run the xpath expression against the document. That's the set you would then canonicalize and encode.

Rob
--
You received this message because you are subscribed to the Google Groups "xmlseclibs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to xmlseclibs+...@googlegroups.com.
To post to this group, send email to xmlse...@googlegroups.com.
Visit this group at http://groups.google.com/group/xmlseclibs.
For more options, visit https://groups.google.com/d/optout.

Tejas Trivedi

unread,
Nov 28, 2014, 4:53:02 AM11/28/14
to xmlse...@googlegroups.com
Hi Rob,

For the First Digest , I have removed entire "<ds:Signature" element and then performing below code.

$dom_initial = new DOMDocument();  
$dom_initial->loadXML($xml_initial);
$dom_initial->formatOutput = true;
$dom_initial->preserveWhiteSpace = false;

$xpath = new DOMXPath($dom_initial);
$tag = $xpath->query("//*")->item(0);

$initial_xml_data = $tag->C14N();
$digest1 = base64_encode(sha1($initial_xml_data, TRUE));


Can you suggest , is there anything wrong in above code? Also for the second digest performing same thing. Still I am getting wrong signature.

Can you please comment on this as I already spent nearly 1 month now and not getting this done.

Thanks
xml.xml

Tejas Trivedi

unread,
Dec 1, 2014, 3:34:43 AM12/1/14
to xmlse...@googlegroups.com
Hello,

Anyone in the group , Please can you help?

Thanks

Rob Richards

unread,
Dec 1, 2014, 8:02:13 AM12/1/14
to xmlse...@googlegroups.com
Was a holiday here so just getting back to my email.

Few issues:
you should be preserving whitespace, so remove that line as it's the default.
Your query should be:

not(ancestor-or-self::node()[@soap:actor="urn:oasis:names:tc:ebxml-msg:action:nextMSH"]
|
ancestor-or-self::node()[@soap:actor="http://schemas.xmlsoap.org/soap/actor/next"])

See if that then works. Would need to see the entire raw message to know what the second part looks like.

Rob

Tejas Trivedi

unread,
Dec 1, 2014, 9:24:36 AM12/1/14
to xmlse...@googlegroups.com
Hi Rob,

Thanks for reply. I am very much delighted now that you are there.

I have attached the row xml here.

Can you please see anything wrong in my code?

Thanks,
xml.xml

Tejas Trivedi

unread,
Dec 2, 2014, 3:27:18 AM12/2/14
to xmlse...@googlegroups.com
Hi Rob, 

If I used below code for the first digest then getting error. "PHP Fatal error: Call to a member function C14N() on a non-object"

$dom_initial = new DOMDocument();  
$dom_initial->formatOutput = true;
$dom_initial->loadXML($xml_initial);

$xpath = new DOMXPath($dom_initial);

$tag = $xpath->query('not(ancestor-or-self::node()[@soap:actor="urn:oasis:names:tc:ebxml-msg:actor:nextMSH"]|ancestor-or-self::node()[@soap:actor="http://schemas.xmlsoap.org/soap/actor/next"])')->item(0);

$initial_xml_data = $tag->C14N();
$digest1 = base64_encode(sha1($initial_xml_data, TRUE));


below query will not work?

$tag = $xpath->query("//*")->item(0);

Also , to calculate Digest1 value, I need to take string starts from <soap:Envelope right? Excluding <ds:signature element

Tejas Trivedi

unread,
Dec 2, 2014, 7:14:50 AM12/2/14
to xmlse...@googlegroups.com
Hi Rob,

Attached is the Successful request. Can you replicate how the digest1 and digest2 have been created? I am not able to create same digest values with the request via reverse engineering.

Thanks,

Tejas Trivedi.
request_xml.xml

Rob Richards

unread,
Dec 2, 2014, 7:42:55 AM12/2/14
to xmlse...@googlegroups.com
Only getting intermittent time to look at it but off the bat its not finding any nodes from the xpath query due to namespace issue. I need to look more into the request to see what namespace(s) might not have been properly registered for the xpath query.

Rob

Tejas Trivedi

unread,
Dec 3, 2014, 2:55:49 AM12/3/14
to xmlse...@googlegroups.com
Hi Guys,

I am entering in 6th week now, and I am not able to Sign the message (i.e. not able to generate proper Digest values). Please Help me out. I am running out of time.

Thanks,

Tejas Trivedi.

Tejas Trivedi

unread,
Dec 3, 2014, 7:42:34 AM12/3/14
to xmlse...@googlegroups.com
Hi ,

Attached is the Successful XML request. In that, Digest value of URI="cid:Payload-0" , i am trying to reproduce from my code.

I am taking payload as a string starts with <urn:AddOrder and ends with </urn:AddOrder>. So my $data contains this string.

$dom_following = new DOMDocument();
$dom_following->formatOutput = true;
$dom_following->preserveWhiteSpace = false;
$dom_following->loadXML($data);

$xpath = new DOMXPath($dom_following);
$tag123 = $xpath->query("//*")->item(0);

$following_xml_data = $tag123->C14N();

$digest2 = base64_encode(sha1($following_xml_data, TRUE));

The digest2 value I am getting from this is not equal to "YZEYQ9QL5uaCEZVyoKgUkWo8dB4=" , Can anyone please check and let me know?

Thanks
request_xml.xml

Rob Richards

unread,
Dec 3, 2014, 7:50:09 AM12/3/14
to xmlse...@googlegroups.com
Are you positive that what you sent was the raw binary message? Any formatting of the XML (which includes whitespaces) will alter the values.
The following code should produce the correct digest altho I am not able to produce it with the data you had sent:


$dom_initial = new DOMDocument(); 
$dom_initial->loadXML($xml_initial);

$xpath = new DOMXPath($dom_initial);

$xpath->registerNamespace('secdsig', 'http://www.w3.org/2000/09/xmldsig#');
$query = ".//secdsig:Signature";

$nodeset = $xpath->query($query, $dom_initial);
$sigNode = $nodeset->item(0);
if (! $dom_initial->isSameNode($sigNode)) {
    $sigNode->parentNode->removeChild($sigNode);
}

$xpath_query = 'not(ancestor-or-self::node()[@soap:actor="urn:oasis:names:tc:ebxml-msg:action:nextMSH"] | ancestor-or-self::node()[@soap:actor="http://schemas.xmlsoap.org/soap/actor/next"])';

$arXPath = array();
$arXPath['query'] = '(.//. | .//@* | .//namespace::*)['.$xpath_query.']';
$arXpath['namespaces'] = array();
$arXPath['namespaces']['soap'] = 'http://schemas.xmlsoap.org/soap/envelope/';
$arXPath = NULL;
$initial_xml_data = $dom_initial->C14N(FALSE, FALSE, $arXPath);

$digest1 = base64_encode(sha1($initial_xml_data, TRUE));

echo "actual:   $digest1\n";
echo "expected: JIvV28g5qiXTxPsKyO7RPsU0+JI=\n\n";

Tejas Trivedi

unread,
Dec 3, 2014, 8:43:13 AM12/3/14
to xmlse...@googlegroups.com
Hi Rob,

Thanks for your email. I was waiting for your reply. I don't know but for digest1 what I did : 

For $xml_initial, I removed <ds:Signature> itself and try to generate from remaining with below code and it worked.

$dom_initial = new DOMDocument();  
$dom_initial->formatOutput = true;
$dom_initial->preserveWhiteSpace = false;
$dom_initial->loadXML($xml_initial);

$xpath = new DOMXPath($dom_initial);
$tag = $xpath->query("//*")->item(0);

$initial_xml_data = $tag->C14N();
$digest1 = base64_encode(sha1($initial_xml_data, TRUE));

What you think, this will not work for everytime? However I will try your solution for the first digest. Also Currently facing with Digest 2 value issue where doing same thing.

I am taking payload as a string starts with <urn:AddOrder and ends with </urn:AddOrder>. So my $data contains this string.

$dom_following = new DOMDocument();
$dom_following->formatOutput = true;
$dom_following->preserveWhiteSpace = false;
$dom_following->loadXML($data);

$xpath = new DOMXPath($dom_following);
$tag123 = $xpath->query("//*")->item(0);

$following_xml_data = $tag123->C14N();

$digest2 = base64_encode(sha1($following_xml_data, TRUE));

But this is not working.

Tejas Trivedi

unread,
Dec 3, 2014, 8:57:27 AM12/3/14
to xmlse...@googlegroups.com
Hi Rob,

Thanks. I have tested and it worked. Just i need to add one line in that case is : $dom_initial->preserveWhiteSpace = false; that code worked as charm.

Can you please check for 2nd digest if you get time? Thanks Again.

Rob Richards

unread,
Dec 3, 2014, 9:11:08 AM12/3/14
to xmlse...@googlegroups.com
If that's the case then I would definitely expect it to be a whitespace issue with the documents you attached. Whitespace is significant so if disabling that makes it work then the document definitely is not in the same format as when it was initially sent. I would then think that the second digest has the same issue and you can never know what whitespace was in the origional and what wasn't which is why the second digest may not be working like the first one.

Your canonicalization is only working because the xpath I have in my example (which comes from the XML document) evaluates to the same thing as the document itself. Your canonicalization is not guaranteed to work as in the event there are some matching nodes in the document, you would not be excluding them.

Rob

Tejas Trivedi

unread,
Dec 3, 2014, 9:17:54 AM12/3/14
to xmlse...@googlegroups.com
Hi,

But if I do $dom_initial->preserveWhiteSpace = false; then it won't work for 2nd digest. But you are saying in that case what was the original (Means payload may contains some spaces and we should not shrink it. right?) 

So, in this case I need to put original and need to check. But can you please confirm the payload data I am taking as (starts with <urn:AddOrder and ends with </urn:AddOrder>). Is it right?
...

Rob Richards

unread,
Dec 3, 2014, 9:25:07 AM12/3/14
to xmlse...@googlegroups.com
The payload you are referencing is correct

Rob
--

Tejas Trivedi

unread,
Dec 3, 2014, 11:09:32 PM12/3/14
to xmlse...@googlegroups.com
Hi Rob, 

Thanks again. Regarding generating second digest what I believe is I just need to take payload as a reference and just need to do below stuff.

$digest2 = base64_encode(sha1($following_xml_data, TRUE));

No need to Cannonicalize or xPath for second digest as per below transform algorithm. Right? that I want to confirm. If it is true then i need to check Spaces in the XML only.

<ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
        <ds:Reference URI="">
          <ds:Transforms>
            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
              <ds:XPath>not(ancestor-or-self::node()[@SOAP-ENV:actor="urn:oasis:names:tc:ebxml-msg:actor:nextMSH"] | ancestor-or-self::node()[@SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next"])</ds:XPath>
            </ds:Transform>
            <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
          </ds:Transforms>
          <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
          <ds:DigestValue>Jt8bw4fN9sBJTqiL0/l277KA/UI=</ds:DigestValue>
        </ds:Reference>
        <ds:Reference URI="cid:Payload-0">
          <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
          <ds:DigestValue>YZEYQ9QL5uaCEZVyoKgUkWo8dB4=</ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
...

Tejas Trivedi

unread,
Dec 4, 2014, 8:03:42 AM12/4/14
to xmlse...@googlegroups.com
Hi Rob,

Can you please comment on 2nd digest as per below thread? Here I am attaching my php implementation file which generates digest values and Signature value and send request.

Thanks,
test.php

Rob Richards

unread,
Dec 4, 2014, 10:32:36 AM12/4/14
to xmlse...@googlegroups.com
You are correct. There are no transforms for the second reference so you just need to take the raw data (still may have whitespace issue) and calculate the digest.

Rob
--

Tejas Trivedi

unread,
Dec 4, 2014, 11:46:22 AM12/4/14
to xmlse...@googlegroups.com
Hi Rob,

Thanks for your help. Apologies for disturbing.

Due to whitespaces I am not able to reproduce same digest. But I am now making fresh requests but still getting error about "Security check". Means there is still problem with signature.

So I apologize but I request you can you please check my attached php file in last thread and you can figure out what is wrong.

As now i am running out of ideas and running out of time (almost 5-6 weeks). Can you please check my file and see anything wrong?

Thanks for your constant help.

Tejas Trivedi.

Tejas Trivedi

unread,
Dec 5, 2014, 10:25:20 AM12/5/14
to xmlse...@googlegroups.com
Hi,

If you get a time , can you please go through my PHP Script implementation? and see what is wrong?

Thanks,
test.php

Tejas Trivedi

unread,
Dec 8, 2014, 9:46:54 AM12/8/14
to xmlse...@googlegroups.com
Hi Rob,

Thank you very Much for your constant help.

I used your library, However it was not fit into my requirement, but i modified it wherever applicable and the entire request works well now.

Many many thanks for your help and your efforts for creating the library.

Thank you. Thank you.

Tejas Trivedi.

Rob Richards

unread,
Dec 8, 2014, 10:13:06 AM12/8/14
to xmlse...@googlegroups.com
What modifications did you end up having to make?



On 12/8/14, 9:46 AM, Tejas Trivedi wrote:
Hi Rob,

Thank you very Much for your constant help.

I used your library, However it was not fit into my requirement, but i modified it wherever applicable and the entire request works well now.

Many many thanks for your help and your efforts for creating the library.

Thank you. Thank you.

Tejas Trivedi.

On Friday, December 5, 2014 8:55:20 PM UTC+5:30, Tejas Trivedi wrote:
Hi,

If you get a time , can you please go through my PHP Script implementation? and see what is wrong?

Thanks,

On Thursday, December 4, 2014 10:16:22 PM UTC+5:30, Tejas Trivedi wrote:
Hi Rob,

Thanks for your help. Apologies for disturbing.

Due to whitespaces I am not able to reproduce same digest. But I am now making fresh requests but still getting error about "Security check". Means there is still problem with signature.

So I apologize but I request you can you please check my attached php file in last thread and you can figure out what is wrong.

As now i am running out of ideas and running out of time (almost 5-6 weeks). Can you please check my file and see anything wrong?

Thanks for your constant help.

Tejas Trivedi.
--

Tejas Trivedi

unread,
Dec 9, 2014, 7:15:39 AM12/9/14
to xmlse...@googlegroups.com
Hi Rob,

First of all I adopted your library instead of stand alone code. For second payload I calculated ( <xml version="1.0">) this as well before I was not using this and that makes request success.

Thanks Rob.

Rob Richards

unread,
Dec 9, 2014, 8:45:35 AM12/9/14
to xmlse...@googlegroups.com
Ah that makes sense for the second payload. It is being consumed as raw data and not as XML (where the declaration would not matter in this case).

Rob
Reply all
Reply to author
Forward
0 new messages