{"id":20672788,"url":"https://github.com/selective-php/xmldsig","last_synced_at":"2025-04-06T06:09:41.851Z","repository":{"id":45221429,"uuid":"143132234","full_name":"selective-php/xmldsig","owner":"selective-php","description":"Sign XML Documents with Digital Signatures","archived":false,"fork":false,"pushed_at":"2023-09-09T22:19:42.000Z","size":103,"stargazers_count":74,"open_issues_count":1,"forks_count":35,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T05:05:25.034Z","etag":null,"topics":["abandoned","php","xml","xmldsig","xmldsig-signature"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/selective-php.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-01T09:12:15.000Z","updated_at":"2025-01-23T21:54:07.000Z","dependencies_parsed_at":"2024-06-18T19:48:39.942Z","dependency_job_id":"049818b7-e88d-4428-bbe9-76912a622c21","html_url":"https://github.com/selective-php/xmldsig","commit_stats":{"total_commits":112,"total_committers":5,"mean_commits":22.4,"dds":0.1964285714285714,"last_synced_commit":"adfa81bc744a29f808a5216bf73e0cb2bcd7af91"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/selective-php%2Fxmldsig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/selective-php%2Fxmldsig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/selective-php%2Fxmldsig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/selective-php%2Fxmldsig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/selective-php","download_url":"https://codeload.github.com/selective-php/xmldsig/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247441052,"owners_count":20939239,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abandoned","php","xml","xmldsig","xmldsig-signature"],"created_at":"2024-11-16T20:38:48.380Z","updated_at":"2025-04-06T06:09:41.834Z","avatar_url":"https://github.com/selective-php.png","language":"PHP","readme":"# XMLDSIG for PHP\n\n[![Latest Version on Packagist](https://img.shields.io/github/release/selective-php/xmldsig.svg)](https://packagist.org/packages/selective/xmldsig)\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)\n[![Build Status](https://github.com/selective-php/xmldsig/workflows/build/badge.svg)](https://github.com/selective-php/xmldsig/actions)\n[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/selective-php/xmldsig.svg)](https://scrutinizer-ci.com/g/selective-php/xmldsig/code-structure)\n[![Quality Score](https://img.shields.io/scrutinizer/quality/g/selective-php/xmldsig.svg)](https://scrutinizer-ci.com/g/selective-php/xmldsig/?branch=master)\n[![Total Downloads](https://img.shields.io/packagist/dt/selective/xmldsig.svg)](https://packagist.org/packages/selective/xmldsig/stats)\n\n## Features\n\n* Sign XML Documents with Digital Signatures ([XMLDSIG](https://www.w3.org/TR/xmldsig-core/))\n* Verify the Digital Signatures of XML Documents\n* ECDSA (SHA256) signature\n\n## Requirements\n\n* PHP 8.1+\n* The openssl extension\n* A X.509 digital certificate\n\n## Installation\n\n```\ncomposer require selective/xmldsig\n```\n\n## Usage\n\n### Signing an XML Document with a digital signature\n\nInput file: example.xml\n\n```xml\n\u003c?xml version=\"1.0\"?\u003e\n\u003croot\u003e\n    \u003ccreditcard\u003e\n        \u003cnumber\u003e19834209\u003c/number\u003e\n        \u003cexpiry\u003e02/02/2025\u003c/expiry\u003e\n    \u003c/creditcard\u003e\n\u003c/root\u003e\n```\n\nLoad and add the private key to the `PrivateKeyStore`:\n\n```php\nuse Selective\\XmlDSig\\PrivateKeyStore;\n// ...\n\n$privateKeyStore = new PrivateKeyStore();\n\n// load a private key from a string\n$privateKeyStore-\u003eloadFromPem('private key content', 'password');\n\n// or load a private key from a PEM file\n$privateKeyStore-\u003eloadFromPem(file_get_contents('filename.pem'), 'password');\n\n// load pfx PKCS#12 certificate from a string\n$privateKeyStore-\u003eloadFromPkcs12('pfx content', 'password');\n\n// or load PKCS#12 certificate from a file\n$privateKeyStore-\u003eloadFromPkcs12(file_get_contents('filename.p12'), 'password');\n```\n\nDefine the digest method: sha1, sha224, sha256, sha384, sha512\n\n```php\nuse Selective\\XmlDSig\\Algorithm;\n\n$algorithm = new Algorithm(Algorithm::METHOD_SHA1);\n```\n\nCreate a `CryptoSigner` instance:\n\n```php\nuse Selective\\XmlDSig\\CryptoSigner;\n\n$cryptoSigner = new CryptoSigner($privateKeyStore, $algorithm);\n```\n\nSigning:\n\n```php\nuse Selective\\XmlDSig\\XmlSigner;\n\n// Create a XmlSigner and pass the crypto signer\n$xmlSigner = new XmlSigner($cryptoSigner);\n\n// Optional: Set reference URI\n$xmlSigner-\u003esetReferenceUri('');\n\n// Create a signed XML string\n$signedXml = $xmlSigner-\u003esignXml('\u003c?xml ...');\n\n// or sign an XML file\n$signedXml = $xmlSigner-\u003esignXml(file_get_contents($filename));\n\n// or sign an DOMDocument\n$xml = new DOMDocument();\n$xml-\u003epreserveWhiteSpace = true;\n$xml-\u003eformatOutput = false;\n$xml-\u003eloadXML($data);\n\n$signedXml = $xmlSigner-\u003esignDocument($xml);\n```\n\nOutput:\n\n```xml\n\u003c?xml version=\"1.0\"?\u003e\n\u003croot\u003e\n    \u003ccreditcard\u003e\n        \u003cnumber\u003e19834209\u003c/number\u003e\n        \u003cexpiry\u003e02/02/2025\u003c/expiry\u003e\n    \u003c/creditcard\u003e\n    \u003cSignature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"\u003e\n        \u003cSignedInfo\u003e\n            \u003cCanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/\u003e\n            \u003cSignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512\"/\u003e\n            \u003cReference URI=\"\"\u003e\n                \u003cTransforms\u003e\n                    \u003cTransform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/\u003e\n                \u003c/Transforms\u003e\n                \u003cDigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha512\"/\u003e\n                \u003cDigestValue\u003eBase64EncodedValue==\u003c/DigestValue\u003e\n            \u003c/Reference\u003e\n        \u003c/SignedInfo\u003e\n        \u003cSignatureValue\u003eAnotherBase64EncodedValue===\u003c/SignatureValue\u003e\n    \u003c/Signature\u003e\n\u003c/root\u003e\n```\n\n#### Signing only specific part of an XML document\n\nExample:\n\n```php\nuse Selective\\XmlDSig\\Algorithm;\nuse Selective\\XmlDSig\\CryptoSigner;\nuse Selective\\XmlDSig\\PrivateKeyStore;\nuse Selective\\XmlDSig\\XmlSigner;\nuse DOMDocument;\nuse DOMXPath;\n// ...\n\n// Load the XML content you want to sign\n$xml = new DOMDocument();\n$xml-\u003epreserveWhiteSpace = true;\n$xml-\u003eformatOutput = false;\n$xml-\u003eloadXML($data);\n\n// Create a XPATH query to select the element you want to sign \n$xpath = new DOMXPath($xml);\n\n// Change this query according to your requirements\n$referenceUri = '#1';\n$elementToSign = $xpath-\u003equery( '//*[@Id=\"'. $referenceUri .'\"]' )-\u003eitem(0);\n\n// Add private key\n$privateKeyStore = new PrivateKeyStore();\n$privateKeyStore-\u003eloadPrivateKey('private key content', 'password');\n\n$cryptoSigner = new CryptoSigner($privateKeyStore, new Algorithm(Algorithm::METHOD_SHA1));\n\n// Sign the element\n$xmlSigner = new XmlSigner($cryptoSigner);\n$signedXml = $xmlSigner-\u003esignDocument($xml, $elementToSign);\n```\n\n### Signing an XML Document with ECDSA SHA256\n\nThe Elliptic Curve Digital Signature Algorithm (ECDSA) is the elliptic curve\nanalogue of the Digital Signature Algorithm (DSA).\n\nIt is compatible with OpenSSL and uses elegant math such as Jacobian Coordinates\nto speed up the ECDSA on pure PHP.\n\n**Requirements**\n\n* The [GMP extension](https://www.php.net/manual/en/book.gmp.php) must be installed and enabled.\n\nTo install the package with Composer, run:\n\n```\ncomposer require starkbank/ecdsa\n```\n\n**Example**\n\nNote, you can sign an XML **signature** using ECDSA.\nIt's not supported to use ECDSA for the **digest**.\n\nYou can find a fully working example in the [XmlEcdsaTest](tests/XmlEcdsaTest.php) test class.\n\n### Verify the Digital Signatures of XML Documents\n\nLoad the public key(s):\n\n```php\nuse Selective\\XmlDSig\\PublicKeyStore;\nuse Selective\\XmlDSig\\CryptoVerifier;\nuse Selective\\XmlDSig\\XmlSignatureVerifier;\n\n$publicKeyStore = new PublicKeyStore();\n\n// load a public key from a string\n$publicKeyStore-\u003eloadFromPem('public key content');\n\n// or load a public key file\n$publicKeyStore-\u003eloadFromPem(file_get_contents('cacert.pem'));\n\n// or load a public key from a PKCS#12 certificate string\n$publicKeyStore-\u003eloadFromPkcs12('public key content', 'password');\n\n// or load a public key from a PKCS#12 certificate file\n$publicKeyStore-\u003eloadFromPkcs12(file_get_contents('filename.pfx'), 'password');\n\n// Load public keys from DOMDocument X509Certificate nodes\n$publicKeyStore-\u003eloadFromDocument($xml);\n\n// Load public key from existing OpenSSLCertificate resource\n$publicKeyStore-\u003eloadFromCertificate($certificate);\n```\n\nCreate a `CryptoVerifier` instance:\n\n```php\nuse Selective\\XmlDSig\\CryptoVerifier;\n\n$cryptoVerifier = new CryptoVerifier($publicKeyStore);\n```\n\nVerifying:\n\n```php\nuse Selective\\XmlDSig\\XmlSignatureVerifier;\n\n// Create a verifier instance and pass the crypto decoder\n$xmlSignatureVerifier = new XmlSignatureVerifier($cryptoVerifier);\n\n// Verify XML from a string\n$isValid = $xmlSignatureVerifier-\u003everifyXml($signedXml);\n\n// or verify a XML file\n$isValid = $xmlSignatureVerifier-\u003everifyXml(file_get_contents('signed.xml'));\n\n// or verifying an DOMDocument instance\n$xml = new DOMDocument();\n$xml-\u003epreserveWhiteSpace = true;\n$xml-\u003eformatOutput = false;\n$xml-\u003eloadXML($data);\n\n$isValid = $xmlSignatureVerifier-\u003everifyDocument($xml);\n\nif ($isValid === true) {\n    echo 'The XML signature is valid.';\n} else {\n    echo 'The XML signature is not valid.';\n}\n```\n\n### Online XML Digital Signature Verifier\n\nTry these excellent online tools to verify XML signatures:\n\n* \u003chttps://www.aleksey.com/xmlsec/xmldsig-verifier.html\u003e\n* \u003chttps://tools.chilkat.io/xmlDsigVerify.cshtml\u003e\n\n## Similar libraries\n\n* \u003chttps://github.com/robrichards/xmlseclibs\u003e\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE) for more information.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fselective-php%2Fxmldsig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fselective-php%2Fxmldsig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fselective-php%2Fxmldsig/lists"}