Как создать DigestValue и SignatureValue для конвертированной XML-подписи с помощью инструмента PHP / Linux - PullRequest
3 голосов
/ 27 января 2010

Я пытался найти несколько примеров того, как генерировать DigestValue и SignatureValue для подписи XML (WSDL).

Ниже приведен пример SOAP для приложения:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<SOAP-SEC:Signature soapenv:actor="" soapenv:mustUnderstand="0">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#Body">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue></ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue></ds:SignatureValue>
</ds:Signature>
</SOAP-SEC:Signature>
</soapenv:Header>
<soapenv:Body Id="Body">
<SomeApplicationMethod soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<Application href="#id0"/></SomeApplicationMethod>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:NCDServices" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns1:SomeApplicationMethod">
<param2 xsi:type="soapenc:string">123456</param2>
<param3 xsi:type="soapenc:string">someString</param3>
<param4 xsi:type="soapenc:string">string123 bla bla</param4>
<param5 xsi:type="soapenc:string">0</param5>
</multiRef>
</soapenv:Body>
</soapenv:Envelope> 

У меня есть один пример от поставщика приложений, и я не могу создать тот же DigestValue и SignatureValue, что и в примере. Согласно документации приложения, мне нужно создать digestValue из всего раздела Body.

Я знаю, что мне нужно канонизировать, sha1, затем base64encode. Но как я могу канонизировать секцию тела? (кодирование sha1 и base64 достаточно просто для понимания).

Изначально я хочу попробовать создать строку var:

$whole_body = '<soapenv:Body Id="Body"> ........stuff inside...... </soapenv:Body>';

но потом я обнаружил, что в PHP нет такого понятия, как функция c14n (по крайней мере, для строк типа var и PHP 5.2 и ниже; не беспокойтесь, у меня 5.2.6).

Я посмотрел на код xmlseclibs.php, и он, кажется, использует объект DOMelement для получения функции C14N. Я не очень хорошо знаю, что такое DOMelement ..

Я пытался использовать xmlseclibs.php для подписи своего XML, но, похоже, он не работает, я получил ошибку «подпись не верна» из приложения.

Может ли кто-нибудь помочь просветить новичка (читает я :))?

Большое спасибо за сотрудничество.

Ответы [ 2 ]

2 голосов
/ 15 июля 2010
<?php 

$dom = new DOMDocument();  
$dom->loadXML($yourXML); // the XML you specified above.  

$canonicalized = $dom->C14N(); // for the whole document  

// .. or:  
$tag = $dom->getElementById("yourID"); // give it an ID, or use getElementsByTagName with ->item(0) or something  
$canonicalized = $tag->C14N();  

// $canonicalized is the canonicalized form of the XML   
// So, The DigestValue is just:  
$digest = base64_encode(pack("H*", sha1($canonicalized)));  
?>  

Это должно сработать.

Я также занят XML-DSIG, и мне интересно, какие части можно канонизировать, так как я получил плохую документацию ... :(

1 голос
/ 17 июля 2010

Хм .. Мне действительно удается заставить это работать некоторое время назад.

В итоге я использовал xmlseclibs от Роба Ричардса. http://code.google.com/p/xmlseclibs/

Я предлагаю вам попробовать эту библиотеку, она чрезвычайно проста в использовании.

...