我想使用证书签署 XML 文档。它应该看起来像:
<soapenv:Envelope xmlns:obs="http://csioz.gov.pl/zsmopl/ws/obslugakomunikatow/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" wsu:Id="X509-UUU09456789100000">XXXX==</wsse:BinarySecurityToken><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces PrefixList="obs soapenv" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#id-XYZXYZ1234567890000"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces PrefixList="obs" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>vVYVY4CXo60TYkSZ8S/LQJo/8Zc=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>SIGNATURExxxx</ds:SignatureValue><ds:KeyInfo><wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"><wsse:Reference URI="#X509-UUU09456789100000" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"/></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></soapenv:Header>
<soapenv:Body wsu:Id="id-XYZXYZ1234567890000" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<obs:zapiszKomunikatOS>
<komunikatOS>
...
</komunikatOS>
</obs:zapiszKomunikatOS>
</soapenv:Body>
</soapenv:Envelope>
我尝试使用 XMLSecLibs,但不幸的是它不能很好地工作。首先,我不知道如何使用该工具添加包容性命名空间,也许这是正确签名的关键?我还尝试通过更改对上述模板的引用来复制摘要值和签名值,但它不起作用(我从 SOAP 服务器收到消息:“验证消息时遇到安全错误原因:签名或解密无效”)。
有一些丑陋的代码试图签名:
$communicateFile = __DIR__ . 'template-3.xml';
$pemFilePrv = __DIR__ . '/../cert/15.pem';
$xml = trim(file_get_contents($communicateFile));
$wsseNamespace = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
$wsuNamespace = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
$doc = new \DOMDocument();
$doc->load($communicateFile);
$xp = new \DOMXPath($doc);
$xp->registerNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
$xp->registerNamespace('wsse',$wsseNamespace);
$xp->registerNamespace('wsu',$wsuNamespace);
$xp->registerNamespace('ds',XMLSecurityDSig::XMLDSIGNS);
$securityNode = $xp->query('//wsse:Security')->item(0);
$bodyNode = $xp->query('//soapenv:Body')->item(0);
$objDSig = new XMLSecurityDSig();
$objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
$objDSig->addReference($bodyNode, XMLSecurityDSig::SHA1,NULL,
array('prefix'=>'wsu','prefix_ns'=>$wsuNamespace));
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private'));
$objKey->passphrase = 'XXXXX';
$objKey->loadKey($pemFilePrv, TRUE);
$objDSig->sign($objKey);
$objDSig->insertSignature($securityNode);
有人可以帮我吗?也许只缺少一个包含命名空间?我指望你,因为我没有想法..
此致