simplesamlphp/xml-security
Secure, extensible XML signature and encryption library for PHP (xmldsig/xmlenc). Built on simplesamlphp/xml-common, it helps you sign/verify and encrypt/decrypt XML objects via high-level interfaces, with lower-level APIs available when needed.
## Getting Started
### Minimal Setup
1. **Installation**
Add the package via Composer (ensure PHP 8.0+ with OpenSSL):
```bash
composer require simplesamlphp/xml-security:^2.0
Note: v2.0 enforces stricter XSD-type validation. Ensure your XML schema aligns with W3C standards.
First Use Case: Signing XML (Updated for v2.0)
use SimpleSAML\XML\Security\XMLSecurityKey;
use SimpleSAML\XML\Security\XMLSecurityDSig;
// Generate/load key (PEM format required)
$key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, ['type' => 'private']);
$key->loadKey(file_get_contents(storage_path('app/keys/saml_private.pem')), true);
// Initialize with strict XSD validation (v2.0 default)
$objDSig = new XMLSecurityDSig($key, XMLSecurityDSig::ELEMENT | XMLSecurityDSig::EXCL_C14N);
$objDSig->setCanonicalizationMethod(XMLSecurityDSig::EXCL_C14N); // Explicit for clarity
// Sign with XSD-aware reference
$objDSig->addReference(
'//*[local-name()="Assertion"]',
XMLSecurityDSig::EXCL_C14N,
['http://www.w3.org/2001/10/xml-excl-c14n#'],
['http://www.w3.org/2000/09/xmldsig#sha256']
);
$objDSig->appendSignatureToNode($xmlDoc->documentElement);
$signedXml = $objDSig->sign($key);
Key Resources
tests/ directory (check for XSD validation test cases).SAML Assertion Signing with XSD Validation
// Load SAML response (ensure it validates against XSD)
$samlXml = simplexml_load_string($samlResponse);
libxml_clear_errors(); // Reset before validation
$validator = new \DOMDocument();
$validator->loadXML($samlResponse);
if ($validator->schemaValidate('saml-schema-provider.xsd')) {
// Proceed with signing
$key = $this->samlKeyManager->getPrivateKey();
$objDSig = new XMLSecurityDSig($key, XMLSecurityDSig::ELEMENT);
$objDSig->addReference('//*[local-name()="Assertion"]', XMLSecurityDSig::EXCL_C14N);
$objDSig->appendSignatureToNode($samlXml->xpath('//*[local-name()="Response"]')[0]);
} else {
throw new \InvalidArgumentException("SAML response fails XSD validation");
}
Verifying Signatures with Strict XSD Checks
$objDSig = new XMLSecurityDSig();
$objDSig->idKeys = true;
$objDSig->setStrictXsdValidation(true); // v2.0 feature
// Validate XML structure before verification
$xmlDoc = new \DOMDocument();
$xmlDoc->loadXML($samlResponse);
if (!$xmlDoc->schemaValidate('saml-schema-provider.xsd')) {
throw new \RuntimeException("Invalid SAML structure");
}
$verified = $objDSig->verify($xmlDoc);
if (!$verified) {
throw new \RuntimeException("Signature verification failed (XSD mismatch?)");
}
Key Management (v2.0 Compliance)
openssl genpkey -algorithm RSA -out saml_private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in saml_private.pem -out saml_public.pem
'saml' => [
'key_paths' => [
'private' => storage_path('app/keys/saml_private.pem'),
'public' => storage_path('app/keys/saml_public.pem'),
],
'xsd_schema' => resource_path('schemas/saml-schema-provider.xsd'),
],
Integration with Laravel HTTP (v2.0)
// Middleware with XSD pre-validation
public function handle($request, Closure $next) {
$xml = simplexml_load_string($request->getContent());
$validator = new \DOMDocument();
$validator->loadXML($request->getContent());
if (!$validator->schemaValidate(config('saml.xsd_schema'))) {
abort(400, "Invalid SAML structure");
}
$this->verifySignature($xml);
return $next($request);
}
RSA_SHA256 or RSA_SHA512 for XSD compliance.XMLSecurityException for type mismatches:
try {
$objDSig->sign($key);
} catch (\SimpleSAML\XML\Security\XMLSecurityException $e) {
Log::error("XSD validation failed: " . $e->getMessage());
throw new \RuntimeException("Invalid XML structure");
}
XSD Validation Failures
XMLSecurityException.ID attributes on signed elements.ds: vs xmlns:ds).Issuer in SAML).// Enable strict XSD error reporting
$objDSig->setStrictXsdValidation(true);
$objDSig->debug = true; // Logs XSD validation steps
Key Format Strictness
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in old_key.pem -out new_key.pem
Canonicalization Mismatches
EXCL_C14N but may reject non-compliant XML.$c14n = new XMLSecurityC14N(true, 'http://www.w3.org/2001/10/xml-excl-c14n#');
$canonicalized = $c14n->canonicalize($xmlDoc);
Performance with Large XML
XMLSecurityDSig::DETACHED mode.DOMDocument::schemaValidate().$validator = new \DOMDocument();
$validator->validationErrorHandler = function($err) {
Log::error("XSD Error: " . $err->getMessage());
};
$validator->loadXML($xml);
$key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256);
if (!$key->type === XMLSecurityKey::RSA_SHA256) {
throw new \RuntimeException("Unsupported key type");
}
$objDSig->debugOutput = true; // Logs to stderr
$objDSig->debug = true; // Includes XSD validation steps
class SamlXsdValidator {
public function validate(string $xml): bool {
$validator = new \DOMDocument();
$validator->loadXML($xml);
return $validator->schemaValidate(resource_path('schemas
How can I help you explore Laravel packages today?