snowiow / x509ds
X509签名库
Requires
- php: ^7.1
Requires (Dev)
- codeception/specify: ^1.1
- phpunit/phpunit: 7.0.3
This package is not auto-updated.
Last update: 2024-09-21 00:34:31 UTC
README
简介
X509DS是一个库,可以帮助处理向X509认证请求添加数字签名节点的繁琐过程。一个X509请求通常看起来像这样
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsa:Action xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing/" soapenv:actor="" soapenv:mustUnderstand="0">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT </wsa:Action> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:actor="" soapenv:mustUnderstand="1"> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="timestamp"> <wsu:Created>2015-12-16T13:39:36Z</wsu:Created> <wsu:Expires>2015-12-16T13:44:36Z</wsu:Expires> </wsu:Timestamp> <wsse:BinarySecurityToken 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" 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" wsu:Id="binarytoken">MII...</wsse:BinarySecurityToken> </wsse:Security> </soapenv:Header> <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="body"> <RequestSecurityToken xmlns="http://schemas.xmlsoap.org/ws/2005/02/trust"> <TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</TokenType> <RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</RequestType> </RequestSecurityToken> </soapenv:Body> </soapenv:Envelope>
大多数情况下,您希望将签名附加到头文件中,该文件会散列并规范化XML文档的一些节点。最终,整个签名节点将使用您的x509证书的私钥进行签名。生成的XML文档将看起来像这样
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsa:Action xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing/" soapenv:actor="" soapenv:mustUnderstand="0">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT </wsa:Action> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:actor="" soapenv:mustUnderstand="1"> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="timestamp"> <wsu:Created>2015-12-16T13:39:36Z</wsu:Created> <wsu:Expires>2015-12-16T13:44:36Z</wsu:Expires> </wsu:Timestamp> <wsse:BinarySecurityToken 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" 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" wsu:Id="binarytoken"><MII.../wsse:BinarySecurityToken> </wsse:Security> <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="#body"> <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>Emk...</ds:DigestValue> </ds:Reference> <ds:Reference URI="#timestamp"> <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>2TR...</ds:DigestValue> </ds:Reference> <ds:Reference URI="#binarytoken"> <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>/Ntf...</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>tuO...</ds:SignatureValue> </ds:Signature> </soapenv:Header> <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="body"> <RequestSecurityToken xmlns="http://schemas.xmlsoap.org/ws/2005/02/trust"> <TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</TokenType> <RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</RequestType> </RequestSecurityToken> </soapenv:Body> </soapenv:Envelope>
创建签名的过程相当繁琐,因为您需要在一方面处理加密和openssl,另一方面处理PHP []DOMDocument](https://secure.php.net/manual/en/dom.setup.php)。此库旨在提供创建数字签名的简单接口。创建数字签名的PHP代码,如前面的示例所示,将看起来像这样
use X509DS\Signer; $signer = Signer::fromPrivateKey('path/to/pkey'); $signer->setTags( [ 'Body' => '#body', 'Timestamp' => '#timestamp', 'BinarySecurityToken' => '#binarytoken', ] ); $signer->setCanonization(Canonization::C14N_EXCLUSIVE); $document = $signer->sign(self::XML); //The signed DOMDocument $document->saveXml(); //The signed XML document as a string
如您所见,整个过程不超过4条语句。当然,您可以配置不同的签名构建方式。更多关于此主题的内容,请参阅高级用法部分。
需求
安装
通过composer
composer require snowiow/x509ds
用法
创建签名对象
从私钥或pfx创建。
私钥
// Either from the path of the private key $signer = Signer::fromPrivateKey('path/to/pkey'); // or the string content of the private key $signer = Signer::fromPrivateKey(file_get_contents('path/to/pkey')); // or an openssl resource $signer = Signer::fromPrivateKey(openssl_pkey_get_private(file_get_contents('path/to/pkey')));
pfx文件
// Either from the path of the pfx file $signer = Signer::fromPfx('/path/to/pfx', 'password of pfx'); // or the string content of the pfx file $signer = Signer::fromPfx(file_get_contents('/path/to/pfx'), 'password of pfx');
设置规范化方法。默认:C14N
// Can be one of $signer->setCanonization(Canonization::C14N); //Default $signer->setCanonization(Canonization::C14N_EXCLUSIVE); $signer->setCanonization(Canonization::C14N_WITH_COMMENTS); $signer->setCanonization(Canonization::C14N_WITH_COMMENTS_EXCLUSIVE);
设置摘要方法。默认:SHA1
// Can be one of $signer->setDigestMethod(Digest::SHA1); //Default $signer->setDigestMethod(Digest::SHA256); $signer->setDigestMethod(Digest::SHA512); $signer->setDigestMethod(Digest::RIPEMD160);
设置签名方法。默认:SHA1
// Can be one of $signer->setSignatureMethod(Digest::SHA1); //Default $signer->setSignatureMethod(Digest::SHA256); $signer->setSignatureMethod(Digest::SHA512); $signer->setSignatureMethod(Digest::RIPEMD160);
设置目标。默认:Header
签名节点可以作为子节点附加到任意节点。
// Example values (namespace doesn't need to be given) $signer->setTarget('Header'); //Default $signer->setTarget('Body');
设置标签。默认:[]
设置节点名称,您需要在签名中获取摘要值。该方法被称为setTags,因为节点将通过DOMDocument方法getElementsByTagName进行搜索。稍后版本将添加额外的功能,如getElementsByTagNameNS和getElementById。标签必须是一个数组,其中键是节点名称,值是uri,它将作为摘要值的参考节点的属性设置。
// Example $signer->setTag( [ 'Body' => '#body', 'Timestamp' => '#timestamp', 'BinarySecurityToken' => '#binarytoken', ] );
设置安全令牌引用节点(可选)
有时需要额外的安全令牌引用节点。该节点将添加到签名中,并看起来像这样
<ds:KeyInfo> <wsse:SecurityTokenReference> <wsse:Reference URI="#binarySecurityToken"> </wsse:SecurityTokenReference> </ds:KeyInfo>
uri可以进行配置
// Example $signer->setSecurityTokenReference('#binarySecurityToken');
签名文档
最后,您可以签名字符文档。这将返回带有签名节点的修改后的DOMDocument
$signedDoc = $signer->sign('path/to/xml'); // from a path $signedDoc = $signer->sign(file_get_contents('path/to/xml')); // from a content string // or from a DOMDocument $document = new DOMDocument(); $document->load('path/to/xml'); $signedDoc = $signer->sign($document);
从pfx文件获取证书
因为pfx文件包含私钥和证书,所以您也可以检索提取的证书,例如将其插入BinarySecurityToken节点
$signer = Signer::fromPfx('/path/to/pfx', 'password of pfx'); $cert = $signer->getCertificate();