我正在尝试为我的 PHP SOAP 客户端实现 WS-Security。第一步是能够从传出请求中生成有效的 XML 摘要,但我无法做到这一点。几天来我一直在寻找答案,但大多数答案最终都是“不要自己解决,只需使用现有的 Java 库”。这在我目前的情况下是不可行的。
我一直在网上查看几个示例,试图重现他们拥有的相同摘要,例如来自 Microsoft的这个。该页面列出了以下示例:
<ds:Object Id="ts-text">
Wed Jun 4 12:11:06 EDT
</ds:Object>
然后他们显示预期的摘要值:
<ds:Reference URI="#ts-text">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>pN3j2OeC0+/kCatpvy1dYfG1g68=</ds:DigestValue>
</ds:Reference>
这是我用来计算摘要值的代码:
<?php
$digest = base64_encode(hash('SHA1', $contents, true));
我尝试了许多不同的组合来删除空格或仅使用没有 XML 标记的时间戳但没有成功。我还尝试了需要规范化的更复杂的示例。这是我的单元测试之一:
public function testCreateDigest(DOMDocument $request, $expectedDigest) {
$ns = $request->documentElement->namespaceURI;
$body = $request
->getElementsByTagNameNS($ns, 'Body')
->item(0);
$firstElement = '';
foreach($body->childNodes as $node){
if ($node->nodeType === XML_ELEMENT_NODE) {
$firstElement = $node;
break;
}
}
$content = $firstElement->C14N(false, true);
$actualDigest = base64_encode(hash('SHA1', $content, true));
$this->assertEquals($expectedDigest, $actualDigest);
}
我到底应该散列什么?我错过了任何步骤吗?