php - XML signature differences between HEREDOC and DOMDocument -
an api client have developed works xml messages , messages signed according xml signature syntax , processing specification. after long struggle, got signatures working.
at moment building xml heredoc (simply php strings) , cleanup, i'd create xml domdocument directly. however, causes message invalidated server.
this current setup (server accepts message when signed):
$xml = <<<eot <?xml version="1.0" encoding="utf-8"?> <directoryreq xmlns="http://www.idealdesk.com/ideal/messages/mer-acq/3.3.1" version="3.3.1"> <createdatetimestamp>$timestamp</createdatetimestamp> <merchant> <merchantid>$merchantid</merchantid> <subid>$subid</subid> </merchant> </directoryreq> eot; $document = new domdocument(); $document->loadxml($xml);
this oo approach (server rejects message when signed):
$document = new domdocument('1.0', 'utf-8'); $request = $document->createelement('directoryreq'); $xmlns = $document->createattribute('xmlns'); $xmlns->value = 'http://www.idealdesk.com/ideal/messages/mer-acq/3.3.1'; $version = $document->createattribute('version'); $version->value = '3.3.1'; $request->appendchild($xmlns); $request->appendchild($version); $merchant = $document->createelement('merchant'); $merchant->appendchild($document->createelement('merchantid', $merchantid)); $merchant->appendchild($document->createelement('subid', $subid)); $request->appendchild($document->createelement('createdatetimestamp', $timestamp)); $request->appendchild($merchant); $document->appendchild($request);
what can cause difference such xml signature invalidated server? code sign message same. server reporting "invalid electronic signature".
if required can show more code.
edit, more output , comparison of xml generated
to give more information, output of first (heredoc) xml, generated via $document->savexml()
:
<?xml version="1.0" encoding="utf-8"?> <directoryreq xmlns="http://www.idealdesk.com/ideal/messages/mer-acq/3.3.1" version="3.3.1"> <createdatetimestamp>2013-08-10t19:41:20.000z</createdatetimestamp> <merchant> <merchantid>0020xxxxxx</merchantid> <subid>0</subid> </merchant> </directoryreq>
this output ($document->savexml()
) second (direct domdocument generation) method:
<?xml version="1.0" encoding="utf-8"?> <directoryreq xmlns="http://www.idealdesk.com/ideal/messages/mer-acq/3.3.1" version="3.3.1"> <createdatetimestamp>2013-08-10t19:41:20.000z</createdatetimestamp> <merchant> <merchantid>0020xxxxxx</merchantid> <subid>0</subid> </merchant> </directoryreq>
in php, var_dump()
gives exact same string length. if compare both strings (===
obviously) same. comparing both objects, not same.
signing example
signing occurs library xmlseclibs code (nb. both types signed same way!):
public function sign(domdocument $document, $fingerprint, $keyfile, $passphrase = null) { $dsig = new xmlsecuritydsig(); $dsig->setcanonicalmethod(xmlsecuritydsig::exc_c14n); $dsig->addreference($document, xmlsecuritydsig::sha256, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature'), array('force_uri' => true) ); $key = new xmlsecuritykey(xmlsecuritykey::rsa_sha256, array('type' => 'private')); if ($passphrase !== null) { $key->passphrase = $passphrase; } $key->loadkey($keyfile, true); $dsig->sign($key); $dsig->addkeyinfoandname($fingerprint); $dsig->appendsignature($document->documentelement); }
if dump xml after it's signed, <digestvalue>
, <signaturevalue>
values different. server is correct signature invalid, cannot come clue why method works , b not.
you overwriting $merchant
when create merchant
element, rename variable
$merchantelement = $document->createelement('merchant');
Comments
Post a Comment