Php herdoc和DOMDocument之间的XML签名差异

Php herdoc和DOMDocument之间的XML签名差异,php,xml,domdocument,xml-signature,xmlseclibs,Php,Xml,Domdocument,Xml Signature,Xmlseclibs,我开发的一个API客户机处理XML消息,消息根据规范进行签名。经过长时间的斗争,我终于让签名生效了 现在我正在用herdoc(简单的php字符串)构建XML,通过清理,我想直接用DOMDocument创建XML。但是,这会导致服务器使消息无效 这是当前设置(服务器签名时接受此消息): 什么会导致这种差异,比如XML签名被服务器失效?为消息签名的代码完全相同。服务器只是报告“无效的电子签名” 如果需要,我可以显示更多的代码 编辑、更多输出和比较生成的XML 为了提供更多信息,这是通过$docume

我开发的一个API客户机处理XML消息,消息根据规范进行签名。经过长时间的斗争,我终于让签名生效了

现在我正在用herdoc(简单的php字符串)构建XML,通过清理,我想直接用DOMDocument创建XML。但是,这会导致服务器使消息无效

这是当前设置(服务器签名时接受此消息):

什么会导致这种差异,比如XML签名被服务器失效?为消息签名的代码完全相同。服务器只是报告“无效的电子签名”

如果需要,我可以显示更多的代码

编辑、更多输出和比较生成的XML

为了提供更多信息,这是通过
$document->saveXml()
生成的第一个(herdoc)xml的输出:

在php中,
var\u dump()
给出了完全相同的字符串长度。如果我比较两个字符串(
=
显然),它们是相同的。比较两个对象,则它们不相同

签名示例

使用此代码对库进行签名(注意,两种类型的签名方式相同!):


如果在签名后转储XML,则
的值是不同的。因此服务器是正确的签名是无效的,但我无法找到方法a工作而方法B不工作的线索。

当您创建
merchant
元素时,您正在覆盖
$merchant
,所以只需重命名变量即可

$merchantElement = $document->createElement('Merchant');

我现在通过再次导出和导入XML解决了这个问题。这很难看,但是允许我灵活地处理DOMNodes

protected function repairDOMDocument(DOMDocument $document)
{
    $xml = $document->saveXML();

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

    return $document;
}

如果有人建议如何停止这样做,我很高兴听到这样的建议。

这是一个输入错误,因为我从数组中获取了数据,并将其复制/粘贴到可读性稍高的格式中。所有的值都是根据需要注入的,恐怕问题是另外一回事。无论如何,谢谢你的回答:)@JurianSluiman如果没有实际的代码,你将无法获得太多帮助这里是XML输出和签名函数的示例。摘要和签名本身不同,导致给定错误。。这也可以解释你的经历。你当时给出的答案听起来只是误导(充其量),以防phpseclibs中出现错误。没有必要重新发明轮子,方法被调用,这与“修复”无关顺便说一句(“重新加载”应该是一个更好的术语,因为这正是你正在做的).阅读您在我的问题的评论中发布的链接,我可能会通过替换
$xmlns=$document->createAttribute('xmlns')来解决这个问题$xmlns->value=http://www.idealdesk.com/ideal/messages/mer-acq/3.3.1';通过
$document->setAttributeNS('http://www.idealdesk.com/ideal/messages/mer-acq/3.3.1)
。我现在没有时间研究它,但是谢谢你的回答,我会检查它的!如果它不起作用,我将尝试
normalizeDocument()
作为替代方案。
<?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>
<?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>
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);
}
$merchantElement = $document->createElement('Merchant');
protected function repairDOMDocument(DOMDocument $document)
{
    $xml = $document->saveXML();

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

    return $document;
}