Mat*_*ttA 16 php xml ws-security soap web-services
我正在使用客户端,尝试使用PHP发送和接收soap调用.他们设置了ws-security,并使用x.509证书进行身份验证.我已经能够使用SoapUI使这个工作,但我无法在PHP中使用它.
我遇到的问题是,他们不使用标准的二进制安全令牌或用户名/密码组合.他们在安全令牌参考中签署XML文件.
我一直在尝试使用Rob Richards的库来生成哈希,并且它似乎包含在其中的代码来完成我正在尝试做的事情,但我一直没有成功实现它.(https://github.com/robrichards/wse-php)
这是我们应该得到的:
<soapenv:Envelope xmlns:ord="http://order.pine.cypresscare.com" 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">
<ds:Signature Id="SIG-17020931F46DA4F12E144355764463230" 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="ord soapenv" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
<ds:Reference URI="#id-17020931F46DA4F12E144355764463229">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="ord" 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>BZc+DagseonF6kbBdtONG73wjcE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>eIICrWiZerxelcSNUack5OKgvdSKYS3p5KdblFLVztYksExNoZ9wLQ==</ds:SignatureValue>
<ds:KeyInfo Id="KI-17020931F46DA4F12E144355764463227">
<wsse:SecurityTokenReference wsu:Id="STR-17020931F46DA4F12E144355764463228">
<wsse:KeyIdentifier 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#X509v3">
MIID... (Hash goes here)
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>
Run Code Online (Sandbox Code Playgroud)
但我能得到的最好的是:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ord="http://order.pine.cypresscare.com">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="pfx7b827e06-1662-e6e4-78fd-6b4bb95aeb96" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
MIIC... (Hash goes here)
</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#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#pfx0b88133b-03ed-8bbc-8c8a-4998ef427a3a">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>fPmwf05DIdXW4K9muNYR6LMXjnI=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>q36Dr2TIl1OE0/6bBMPb0dQRVCimwpOx7KeYyUCfxMZVIMvDBXxH+lCiB5xEgEH/aceUsn19b0GTU1LqISOk4/rhVBHGw2Wpq/jBcRZWOO54xZYdpGkqzepagazJWOWVVdDCAD7WpQV34KRu1rT4S4ZCjaOeApVIlI2nhPWRXVQ=</ds:SignatureValue>
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#pfx7b827e06-1662-e6e4-78fd-6b4bb95aeb96"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>
Run Code Online (Sandbox Code Playgroud)
并且PHP类使这一切工作:
<?php
class MySoap extends SoapClient {
public function __doRequest($request, $location, $saction, $version) {
$doc = new DOMDocument('1.0');
$doc->loadXML($request);
$objWSSE = new WSSESoap($doc);
/* add Timestamp with no expiration timestamp */
$objWSSE->addTimestamp();
/* create new XMLSec Key using AES256_CBC and type is private key */
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
/* load the private key from file - last arg is bool if key in file (true) or is string (false) */
$objKey->loadKey("c:\\xampp\htdocs\\XMLSoapApp\\cert1.pem", $isFile=true, true);
/* Sign the message - also signs appropiate WS-Security items */
$options = array("insertBefore" => true);
$objWSSE->signSoapDoc($objKey, $options);
/* Add certificate (BinarySecurityToken) to the message */
$token = $objWSSE->addBinaryToken(file_get_contents(combine_key));
/* Attach pointer to Signature */
$objWSSE->attachTokentoSig($token);
return $doc->saveXML();
}
}
Run Code Online (Sandbox Code Playgroud)
必须有一种方法可以毫不费力地做到这一点,但我似乎错过了它.有没有人这样做过?
据我所知,您使用了错误的密钥类型:它应该是XMLSecurityKey::DSA_SHA1,但您正在使用XMLSecurityKey::RSA_SHA1. 顺便说一句,第一个不受库支持。但还是可以解决的。您可以在下面找到我用来测试此功能的代码。
openssl dsa -in dsakey.private
openssl req -x509 -new -days 3650 -key dsakey.private -out dsakey.cert
openssl dsa -in dsakey.private -pubout -out dsakey.pub
Run Code Online (Sandbox Code Playgroud)
在vendor/robrichards/xmlseclibs/src/XMLSecurityKey.php第 216 行添加以下 case 块:
case (self::DSA_SHA1):
$this->cryptParams['library'] = 'openssl';
$this->cryptParams['method'] = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1';
$this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
$this->cryptParams['digest'] = OPENSSL_ALGO_SHA1;
if (is_array($params) && ! empty($params['type'])) {
if ($params['type'] == 'public' || $params['type'] == 'private') {
$this->cryptParams['type'] = $params['type'];
break;
}
}
throw new Exception('Certificate "type" (private/public) must be passed via parameters');
break;
Run Code Online (Sandbox Code Playgroud)
openssl dsa -in dsakey.private
openssl req -x509 -new -days 3650 -key dsakey.private -out dsakey.cert
openssl dsa -in dsakey.private -pubout -out dsakey.pub
Run Code Online (Sandbox Code Playgroud)
case (self::DSA_SHA1):
$this->cryptParams['library'] = 'openssl';
$this->cryptParams['method'] = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1';
$this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
$this->cryptParams['digest'] = OPENSSL_ALGO_SHA1;
if (is_array($params) && ! empty($params['type'])) {
if ($params['type'] == 'public' || $params['type'] == 'private') {
$this->cryptParams['type'] = $params['type'];
break;
}
}
throw new Exception('Certificate "type" (private/public) must be passed via parameters');
break;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2517 次 |
| 最近记录: |