我想创建一些必须包含摘要值的 XML,即规范(C14N)形式的一些 XML 的 BASE64 编码哈希值,但接收方不接受我的代码计算的值,也不接受根据完成后的 XML到(错误的)文档(并且计算与预期值匹配) - 除非我做了一个对我没有意义的肮脏黑客。
幸运的是,我可以访问现有系统,它允许我比较接收者的期望,在那里我可以看到我的计算给出了另一个结果,而不是当我的代码创建与现有系统相同的 XML 时计算的现有系统,但我意识到(阅读后(错误的)文档)XML应该有一些额外的命名空间属性——突然我的代码计算出了正确的摘要值!?!
即,我可以通过两次创建 XML 来计算正确的摘要值!一个带有不正确的 XML(如(错误)文档中所述)并存储计算值,然后存储第二个版本,其中代码从第一次传递中插入计算值。
这会为任何人敲响警钟吗?有人在丹麦健康数据管理局工作吗?
我有以下辅助功能:
function createElement(\DOMDocument $xml, \DOMNode /*DOMDocument&DOMElement*/ $parent, string $name) : \DOMElement {
$node = $xml->createElement($name) or die("<span class=\"fail\">createElement($name) failed</span>");
return $parent->appendChild($node);
}
function createElementNS(\DOMDocument $xml, \DOMNode /*DOMDocument&DOMElement*/ $parent, string $ns, string $name) : \DOMElement {
$node = $xml->createElementNS($ns, $name) or die("<span class=\"fail\">createElementNS(..., $ns, $name) failed</span>");
return $parent->appendChild($node);
}
function createAttribute(\DOMDocument $xml, \DOMElement $parent, string $name, string $value) : \DOMAttr {
$attribute = $xml->createAttribute($name) or die("<span class=\"fail\">createAttribute(..., $name, $value) failed</span>");
$attribute->value = $value;
return $parent->appendChild($attribute);
}
function createAttributeNS(\DOMDocument $xml, \DOMElement $parent, string $name, string $value) : \DOMAttr {
$attribute = $xml->createAttribute($name) or die("<span class=\"fail\">createAttribute{NS}(..., $name, $value) failed</span>");
$attribute->value = $value;
return $parent->appendChild($attribute);
}
function createTextNode(\DOMDocument $xml, \DOMElement $parent, string $text) : \DOMText {
$text_node = $xml->createTextNode($text) or die("<span class=\"fail\">createTextNode($text) failed</span>");
return $parent->appendChild($text_node);
}
和代码的摘录看起来像这样
$hack_pass = 0;
while (++$hack_pass <= 2) {
$xml = new \DOMDocument('1.0', 'UTF-8');
$xml_soapenv_envelope = createElementNS($xml, $xml, 'http://schemas.xmlsoap.org/soap/envelope/', 'soapenv:Envelope');
createAttributeNS($xml, $xml_soapenv_envelope, 'xmlns:ds', 'http://www.w3.org/2000/09/xmldsig#');
...
createAttribute($xml, $xml_soapenv_envelope, 'id', 'Envelope');
$xml_soapenv_header = createElement($xml, $xml_soapenv_envelope, 'soapenv:Header');
$xml_wsse_security = createElement($xml, $xml_soapenv_header, 'wsse:Security');
$xml_wsu_timestamp = createElement($xml, $xml_wsse_security, 'wsu:Timestamp');
$xml_wsu_created = createElement($xml, $xml_wsu_timestamp, 'wsu:Created');
createTextNode($xml, $xml_wsu_created, $created);
if ($hack_pass == 1) {
$xml_saml_assertion = createElementNS($xml, $xml_wsse_security, 'urn:oasis:names:tc:SAML:2.0:assertion', 'saml:Assertion');
} else {
$xml_saml_assertion = createElement($xml, $xml_wsse_security, 'saml:Assertion'); // Final XML
}
...
if ($hack_pass < 2) {
$c14n = $xml_saml_assertion->C14N(TRUE);
$DigestValue = base64_encode(hash('sha1', $c14n, TRUE));
}
...
}