{"id":19794136,"url":"https://github.com/simplesamlphp/xml-security","last_synced_at":"2025-05-01T02:30:56.839Z","repository":{"id":43754226,"uuid":"293582796","full_name":"simplesamlphp/xml-security","owner":"simplesamlphp","description":"SimpleSAMLphp library for XML Security","archived":false,"fork":false,"pushed_at":"2025-04-05T08:22:37.000Z","size":1393,"stargazers_count":2,"open_issues_count":2,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-05T09:24:43.739Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simplesamlphp.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2020-09-07T16:49:08.000Z","updated_at":"2025-04-05T08:22:34.000Z","dependencies_parsed_at":"2023-02-19T12:16:17.743Z","dependency_job_id":"3543f9ef-feaf-4360-adcb-03fca39d5db8","html_url":"https://github.com/simplesamlphp/xml-security","commit_stats":{"total_commits":499,"total_committers":9,"mean_commits":55.44444444444444,"dds":0.406813627254509,"last_synced_commit":"da3bc2d55dec0adc68058a99c0fda9f97dba0234"},"previous_names":[],"tags_count":105,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simplesamlphp%2Fxml-security","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simplesamlphp%2Fxml-security/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simplesamlphp%2Fxml-security/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simplesamlphp%2Fxml-security/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simplesamlphp","download_url":"https://codeload.github.com/simplesamlphp/xml-security/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251812305,"owners_count":21647884,"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":[],"created_at":"2024-11-12T07:12:11.247Z","updated_at":"2025-05-01T02:30:56.301Z","avatar_url":"https://github.com/simplesamlphp.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xml-security\n\n![Build Status](https://github.com/simplesamlphp/xml-security/actions/workflows/php.yml/badge.svg)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/simplesamlphp/xml-security/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/simplesamlphp/xml-security/?branch=master)\n[![Coverage Status](https://codecov.io/gh/simplesamlphp/xml-security/branch/master/graph/badge.svg)](https://codecov.io/gh/simplesamlphp/xml-security)\n[![PHPStan Enabled](https://img.shields.io/badge/PHPStan-enabled-brightgreen.svg?style=flat)](https://github.com/simplesamlphp/xml-security)\n\nThis library implements XML signatures and encryption. It provides an extensible\ninterface that allows you to use your own signature and encryption\nimplementations, and deals with everything else to sign, verify, encrypt and\ndecrypt your XML objects. It is built on top of the [xml-common](https://github.com/simplesamlphp/xml-common)\nlibrary, which provides you with a standard API to create PHP objects from their\nXML representation, as well as producing XML from your objects. The aim of the\nlibrary is to provide a secure, yet flexible implementation of the xmldsig and\nxmlenc standards in PHP.\n\nThe library provides two main ways to use it, one API for signed XML documents,\nand another for encrypted ones. Additionally, the lower level APIs are\navailable to implement those operations yourself if needed, although we highly\nrecommend using the main interfaces.\n\n## Signature API\n\nThe XML signature API consists mainly of two interfaces:\n\n- `SimpleSAML\\XMLSecurity\\XML\\SignableElementInterface`\n- `SimpleSAML\\XMLSecurity\\XML\\SignedElementInterface`\n\nIn general, both should be used together. The former signals that an object can\nbe signed (and as such mandates the implementation of a `sign()` method in the\nobject), while the latter indicates that an object is already signed and allows\nthe verification of its signature by means of `verify()` method.\n\nSince the signature API is provided via PHP interfaces, your objects need to\nimplement those interfaces. For your convenience, each interface is accompanied\nby two traits with the actual implementation for the PHP interfaces:\n\n- `SimpleSAML\\XMLSecurity\\XML\\SignableElementTrait`\n- `SimpleSAML\\XMLSecurity\\XML\\SignedElementTrait`\n\nBoth declare an abstract `getId()` method that you will have to implement, since\nonly you know what attribute is declared in your XML objects to act\nas an `xml:id`.\n\nThe two interfaces mentioned extend from a third one,\n`SimpleSAML\\XMLSecurity\\XML\\CanonicalizableElementInterface`. This interface\nensures that your XML objects can be properly canonicalized, so that if they\nwere created from an actual XML document, it will be possible to restore that\noriginal XML document from your object. Again, a\n`SimpleSAML\\XMLSecurity\\XML\\CanonicalizableElementTrait` is provided for your\nconvenience. This trait implements the canonicalization for you, and ensures\nthat your object can be serialized and later unserialized, but in exchange\nrequires you to implement a `getOriginalXML()` method. This means you will\nhave to keep the original XML that created your object, if any.\n\nIn general, your code should implement both main interfaces and use the traits.\nThe bare minimum you will need to do to add XML signature capabilities to your\nobjects will look like the following:\n\n```php\nnamespace MyNamespace;\n\nuse DOMElement;\nuse SimpleSAML\\XMLSecurity\\XML\\SignableElementInterface;\nuse SimpleSAML\\XMLSecurity\\XML\\SignableElementTrait;\nuse SimpleSAML\\XMLSecurity\\XML\\SignedElementInterface;\nuse SimpleSAML\\XMLSecurity\\XML\\SignedElementTrait;\n\nclass MyObject implements SignableElementInterface, SignedElementInterface\n{\n    use SignableElementTrait;\n    use SignedElementTrait;\n    \n    ...\n    \n    public function getId(): ?string\n    {\n        // return the ID of your object\n    }\n    \n    \n    protected function getOriginalXML(): DOMElement\n    {\n        // return the original XML, if any, or the XML generated by your object\n    }\n}\n```\n\nHowever, we strongly recommend your XML objects to build on top of the API\nprovided by [xml-common](https://github.com/simplesamlphp/xml-common). That way,\nyou should probably have an abstract class to declare your namespace and\nnamespace prefix:\n\n```php\nnamespace MyNamespace;\n\nuse SimpleSAML\\XML\\AbstractElement;\n\nabstract class AbstractMyNSElement extends AbstractElement\n{\n    public const NS = 'my:namespace';\n    \n    public const NS_PREFIX = 'prefix';\n}\n```\n\nThen your object can extend from that:\n\n```php\nnamespace MyNamespace;\n\nuse DOMElement;\nuse SimpleSAML\\XMLSecurity\\XML\\SignableElementInterface;\nuse SimpleSAML\\XMLSecurity\\XML\\SignableElementTrait;\nuse SimpleSAML\\XMLSecurity\\XML\\SignedElementInterface;\nuse SimpleSAML\\XMLSecurity\\XML\\SignedElementTrait;\n\nclass MyObject extends AbstractMyNSElement \n    implements SignableElementInterface, SignedElementInterface\n{\n    use SignableElementTrait;\n    use SignedElementTrait;\n    \n    ...\n    \n    public function getId(): ?string\n    {\n        // return the ID of your object\n    }\n    \n    \n    protected function getOriginalXML(): DOMElement\n    {\n        // return the original XML, if any, or the XML generated by your object\n    }\n    \n    \n    public static function fromXML(DOMElement $xml): object\n    {\n        // build an instance of your object based on an XML document\n        // representing it\n    }\n    \n    \n    public function toXML(DOMElement $parent = null): DOMElement\n    {\n        // build an XML representation of your object\n    }\n}\n```\n\nHave a look at the `CustomSignable` class provided with the tests in this\nrepository to get an idea of how a working implementation could look like.\n\nWhen dealing with XML signatures, you typically need to provide two things:\nthe signature algorithm you want to use and a key. Depending on the\nalgorithm, one type of key or another would be suitable.\nFor that reason, this library introduces the concept of a\n`SignatureAlgorithm`, which is a given instance of an algorithm with a key\nassociated. `SignatureAlgorithm`s can be used then as _signers_\n(when signing an object) and _verifiers_ (when used to verify a signature).\nThis interface, together with the ones provided for key material and signature\nbackends, will allow you to sign and verify signatures without much effort.\n\n### Signing\n\nIf you want to sign an object representing an XML document, the\n`SignableElementTrait` provides you with a `doSign()` method that you can use\nfor your convenience. This method takes the XML document you want to sign, and\nreturns another document result of applying all signature transforms to the\ninput. The _signer_ implementation to use will be obtained from the `$signer`\nproperty of the trait, which in turn will be set by the `sign()` method it\nprovides as well. After the XML is signed successfully, `doSign()` will not only\nreturn the signed version of it, but also populate the `$signature` property\nwith a `Signature` object.\n\nIf you are using the API provided by [xml-common], you would typically\nimplement support for signing your objects like this:\n\n[xml-common]: https://github.com/simplesamlphp/xml-common\n\n```php\n    public function toXML(DOMElement $parent = null): DOMElement\n    {\n        if ($this-\u003esigner !== null) {\n            $signedXML = $this-\u003edoSign($this-\u003egetMyXML());\n            $signedXML-\u003einsertBefore($this-\u003esignature-\u003etoXML($signedXML), $signedXML-\u003efirstChild);\n            return $signedXML;\n        }\n\n        return $this-\u003egetMyXML();\n    }\n```\n\nNote that you will need to implement a mechanism to obtain the actual\n`DOMElement` to sign. It could be a method itself, as depicted in this example,\nor it could be stored in a class property.\n\nAt this point, your object is ready to be signed. You just need to create\na _signer_, pass it to `sign()`, and create the XML representation (which\nwill do the actual signing) by calling `toXML()`:\n\n```php\nuse SimpleSAML\\XMLSecurity\\Constants as C;\nuse SimpleSAML\\XMLSecurity\\Alg\\Signature\\SignatureAlgorithmFactory;\nuse SimpleSAML\\XMLSecurity\\Key\\PrivateKey;\n\n$key = PrivateKey::fromFile('/path/to/key.pem');\n$signer = (new SignatureAlgorithmFactory())-\u003egetAlgorithm(\n    C::SIG_RSA_SHA256,\n    $key\n);\n$myObject-\u003esign($signer);\n$signedXML = $myObject-\u003etoXML();\n```\n\nThat's it, you have signed your first object!\n\nNow, you can customize your signatures as much as you want. For example, you can\nadd the X509 certificate corresponding your private key to it, and specify the\ncanonicalization algorithm to use:\n\n```php\nuse SimpleSAML\\XMLSecurity\\Constants as C;\nuse SimpleSAML\\XMLSecurity\\XML\\ds\\KeyInfo;\nuse SimpleSAML\\XMLSecurity\\XML\\ds\\X509Certificate;\nuse SimpleSAML\\XMLSecurity\\XML\\ds\\X509Data;\n\n...\n\n$keyInfo = new KeyInfo(\n    [\n        new X509Data(\n            [\n                new X509Certificate($base64EncodedCertificateData)\n            ]\n        )\n    ]\n);\n\n$customSignable-\u003esign(\n    $signer,\n    C::C14N_EXCLUSIVE_WITHOUT_COMMENTS,\n    $keyInfo\n);\n\n...\n```\n\nIf you are planning on **embedding your signed object inside a larger\nXML document**, make sure to **give it an unique identifier**. Your\nobject will need to generate an XML with an _ID_ attribute (of type `xml:id`)\nholding the identifier of the element, and the `getId()` method **must** return\nthat very same identifier.\n\n### Verifying\n\nIn order to verify signed objects, the `SignedElementInterface` provides you\nwith the following methods:\n\n- `getId()`: retrieves the unique identifier of the object.\n- `getSignature()`: retrieves the signature of the object as a\n  `SimpleSAML\\XMLSecurity\\XML\\ds\\Signature` object.\n- `getValidatingKey()`: retrieves the key the signature has been verified with.\n- `isSigned()`: tells whether the object is in fact signed or not.\n- `verify()`: verifies the signature of the object.\n\nIf your class has implemented support for signing its objects, and you are\nimplementing the `SignedElementInterface` and using the `SignedElementTrait`,\nsupport for verifying the signatures comes out of the box.\n\nThe process for verifying a signature is similar to the one of creating one.\nYou will need to instantiate a signature verifier with some key material and a\nsignature algorithm, and use it to verify the signature itself:\n\n```php\nuse SimpleSAML\\XMLSecurity\\Alg\\Signature\\SignatureAlgorithmFactory;\nuse SimpleSAML\\XMLSecurity\\Key\\PublicKey;\n\n$verifier = (new SignatureAlgorithmFactory())-\u003egetAlgorithm(\n    $myObject-\u003egetSignature()-\u003egetSignedInfo()-\u003egetSignatureMethod()-\u003egetAlgorithm(),\n    PublicKey::fromFile('/path/to/public-key.pem')\n);\n$verified = $myObject-\u003everify($verifier);\n```\n\n\u003e :warning: WARNING\n\u003e\n\u003e Note the `$verified` variable returned by `verify()`. The method does not\nreturn a `boolean` value to tell you if the signature was verified or not.\nInstead, if it fails to verify, an exception will be thrown. Its return\nvalue then is an object of the same class of your original object\n(`$myObject`), only that it is built based on the XML document whose\nsignature has been verified. **It is very important that you use only objects\nbuilt based on a verified signature**. Otherwise, any possible issue during\nthe signature process could leave you with a tampered object whose signature\ndoesn't really verify.\n\nThere is one alternative way to verify signatures. If the signature itself\ncontains the key we can use to verify it (namely, an X509 certificate), then\nwe can call `verify()` without passing a verifier to it, and check that the\nkey used to verify the signature matches the one we expect:\n\n```php\nuse SimpleSAML\\XMLSecurity\\XML\\ds\\X509Certificate;\n\n$trustedCertificate = new X509Certificate($pemEncodedCertificate);\n$verified = $myObject-\u003everify();\n\nif ($verified-\u003egetValidatingKey() === $trustedCertificate) {\n    // signature verified with a trusted certificate\n}\n```\n\nThis last usage pattern is more convenient since you don't have to create a\n_verifier_, although it forces you to **remember that you need to check the\nkey used to verify the signature**.\n\n## Encryption API\n\nThe XML encryption API is similar to its signature counterpart, and also\nconsists of two main interfaces:\n\n- `SimpleSAML\\XMLSecurity\\XML\\EncryptableElementInterface`\n- `SimpleSAML\\XMLSecurity\\XML\\EncryptedElementInterface`\n\nJust like in the signature API, the former signals that an object can be\nencrypted (and as such requires the implementation of an `encrypt()` method),\nwhile the latter means an object is already encrypted (and therefore requires\na `decrypt()` method to be implemented). There is a substantial difference with\nthe signature API though: you need to implement two different classes, one for\nyour objects themselves, and another for your encrypted objects. The former\nwill then implement `EncryptableElementInterface`, while the latter will be\nthe one implementing `EncryptedElementInterface`.\n\nAgain, the library provides a couple of traits for your convenience, in order\nto minimise the amount of code you have to write. Those traits are:\n\n- `SimpleSAML\\XMLSecurity\\XML\\EncryptableElementTrait`\n- `SimpleSAML\\XMLSecurity\\XML\\EncryptedElementTrait`\n\nBoth traits are somewhat asymmetrical, in the sense that while\n`EncryptableElementTrait` does implement the `encrypt()` method, the\n`EncryptedElementTrait` does not implement its `decrypt()` counterpart.\nThis is because the way objects are encrypted may vary a lot, and the\napplication itself will be the only one that knows exactly how that should\nbe done. A basic default implementation that should cover most use cases\nis provided, though.\n\nAs with digital signatures, we provide classes that demonstrate the encryption\nfunctionality. You may have a look at the `CustomSignable` class provided with\nthe tests in order to see how encryption can be added to your objects, and the\n`EncryptedCustom` class will then demonstrate how to deal with objects that\nare already encrypted.\n\n### Decrypting objects\n\nIn XML encryption, when you have an encrypted object, you typically wrap that\ninside a specific element that signals that the object represents an encrypted\nversion of another object. You may have your own elements and logic in that\nencrypted object, but the absolute minimum would be an `xenc:EncryptedData`\nelement inside. This means you will have to create classes for your encrypted\nobjects, and they will have to implement the `EncryptedElementInterface`.\n\nThe simplest approach is then to take advantage of `EncryptedElementTrait` and\nagain, we recommend taking advantage of the XML object framework provided by\n`simplesamlphp/xml-common`. The only thing you will then have to implement is\nthe `decrypt()` method, and a couple of getters required by the trait:\n\n```php\n\nuse SimpleSAML\\XML\\AbstractElement;\nuse SimpleSAML\\XML\\ElementInterface;\nuse SimpleSAML\\XMLSecurity\\Alg\\Encryption\\EncryptionAlgorithmInterface;\nuse SimpleSAML\\XMLSecurity\\Backend\\EncryptionBackend;\nuse SimpleSAML\\XMLSecurity\\XML\\EncryptedElementInterface;\n\nclass MyEncryptedObject extends AbstractElement\n  implements EncryptedElementInterface\n{\n    use EncryptedElementTrait;\n    \n    \n    public function getBlacklistedAlgorithms(): ?array\n    {\n        // return an array with the algorithms you don't want to allow to be used\n    }\n    \n    \n    public function getEncryptionBackend(): ?EncryptionBackend\n    {\n        // return the encryption backend you want to use,\n        // or null if you are fine with the default\n    }\n    \n    \n    public function decrypt(EncryptionAlgorithmInterface $decryptor): MyObject \n    {\n        // implement the actual decryption here with help from the library\n    }\n}\n```\n\nNote that the value returned by `decrypt()` here is your own `MyObject` class.\nThis means `MyObject` needs to extend `SimpleSAML\\XML\\ElementInterface`, but\nit is also one of the reasons why the implementation of `decrypt()` is left to\nthe application.\n\nNow, the aim of this library is of course to make your life easier so that you\ndon't actually have to implement decryption yourself. The following\nimplementation of `decrypt()` will be suitable for most use cases:\n\n```php\n    public function decrypt(EncryptionAlgorithmInterface $decryptor): MyObject\n    {\n        return MyObject::fromXML(\n            \\SimpleSAML\\XML\\DOMDocumentFactory::fromString(\n                $this-\u003edecryptData($decryptor)\n            )-\u003edocumentElement\n        );\n    }\n```\n\nSo what did just happen here? `MyObject` is supposed to implement\n`ElementInterface`, right? That means it must implement a `fromXML()` static\nmethod that creates a new instance of the class based on what's passed to it as\na `DOMElement` object. The `DOMElement` itself was created with help from the\n`DOMDocumentFactory` class, which in turn took the `string` result of calling\nthe `decryptData()` method provided by the trait. And that's it, that might be\nall you need to decrypt your encrypted objects!\n\nBear in mind though that this is the most basic use case. Your encrypted\nobjects will need to look like this:\n\n```xml\n\u003cMyEncryptedObject\u003e\n  \u003cxenc:EncryptedData xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\"\u003e\n    \u003cxenc:EncryptionMethod Algorithm=\"...\"/\u003e\n    \u003cxenc:CipherData\u003e\n      \u003cxenc:CipherValue\u003e...\u003c/xenc:CipherValue\u003e\n    \u003c/xenc:CipherData\u003e\n  \u003c/xenc:EncryptedData\u003e\n\u003c/MyEncryptedObject\u003e\n```\n\nIf you need any more elements inside, attributes in the root element or anything\nelse, you will have to adjust the implementation for that. In that case, you may\nneed a different constructor for your encrypted objects than the one provided by\nthe trait. You can define your own constructor while taking advantage of the one\nin the trait by renaming the latter:\n\n```php\n\nuse SimpleSAML\\XML\\AbstractElement;\nuse SimpleSAML\\XMLSecurity\\XML\\EncryptedElementInterface;\nuse SimpleSAML\\XMLSecurity\\XML\\xenc\\EncryptedData;\n\nclass MyEncryptedObject extends AbstractElement\n  implements EncryptedElementInterface\n{\n    use EncryptedElementTrait {\n        __construct as constructor;\n    }\n    \n    \n    public function __construct(EncryptedData $encryptedData, ...)\n    {\n        $this-\u003econstructor($encryptedData);\n        \n        ...\n    }\n}\n```\n\nSimilarly, if your encryption scheme does not fit with any of the two supported\nby default, you will also need to implement it yourself. The two encryption\nschemes supported are:\n\n- **Shared key encryption**: both parties share a secret key and use it to\n  encrypt and decrypt the objects, respectively. This means the\n  `\u003cxenc:EncryptionMethod\u003e` element will have a block  cipher specified in\n  the `Algorithm` attribute. The `$decryptor` object passed to the `decrypt()`\n  method will then be created for that block cipher in particular, and the key\n  used will be a  `SimpleSAML\\XMLSecurity\\Key\\SymmetricKey` object with the\n  shared secret as the key material.\n- **Asymmetric encryption**: in this case, public key cryptography is used to\n  encrypt the objects. However, public key cryptography is extremely costly in\n  computational terms, so in a similar fashion to digital signatures, what we do\n  is to generate a random secret or _session key_, which will be used to encrypt\n  the object itself with a block cipher, and in turn we will encrypt that key\n  with the recipient's public key.\n\n  In this case, the `$decryptor` will implement a _key transport_ algorithm\n  (which in turn is just an asymetric encryption algorithm like RSA), and the\n  key attached to it will be a `SimpleSAML\\XMLSecurity\\Key\\PrivateKey` object\n  with the recipient's private key.\n\n  When using asymmetric encryption, your encrypted XML objects will look\n  similar to this:\n\n  ```xml\n  \u003cMyEncryptedObject\u003e\n    \u003cxenc:EncryptedData xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\"\u003e\n      \u003cxenc:EncryptionMethod Algorithm=\"BLOCK CIPHER ALGORITHM IDENTIFIER\"/\u003e\n      \u003cdsig:KeyInfo xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\"\u003e\n        \u003cxenc:EncryptedKey\u003e\n          \u003cxenc:EncryptionMethod Algorithm=\"KEY TRANSPORT ALGORITHM IDENTIFIER\"/\u003e\n          \u003cxenc:CipherData\u003e\n            \u003cxenc:CipherValue\u003e...\u003c/xenc:CipherValue\u003e\n          \u003c/xenc:CipherData\u003e\n        \u003c/xenc:EncryptedKey\u003e\n      \u003c/dsig:KeyInfo\u003e\n      \u003cxenc:CipherData\u003e\n        \u003cxenc:CipherValue\u003e...\u003c/xenc:CipherValue\u003e\n      \u003c/xenc:CipherData\u003e\n    \u003c/xenc:EncryptedData\u003e\n  \u003c/MyEncryptedObject\u003e \n  ```\n  \n  The innermost `\u003cxenc:CipherValue\u003e` will contain the encrypted session key,\n  while the outermost will contain the encrypted object itself.\n\nThe `SimpleSAML\\XMLSecurity\\XML\\EncryptedElementTrait::decryptData()` method is\ncapable of handling both encryption schemes. If your application uses any of\nthose, you can just use the method by passing the appropriate _decryptor_ as\nexplained earlier. If you are using _shared key encryption_, you can then just\ndo the following:\n\n```php\nuse SimpleSAML\\XMLSecurity\\Alg\\Encryption\\EncryptionAlgorithmFactory;\nuse SimpleSAML\\XMLSecurity\\Key\\SymmetricKey;\n\n$decryptor = (new EncryptionAlgorithmFactory())-\u003egetAlgorithm(\n    $myEncryptedObject-\u003egetEncryptedData()-\u003egetEncryptionMethod()-\u003egetAlgorithm(),\n    new SymmetricKey('MY SHARED SECRET')\n);\n$myObject = $myEncryptedObject-\u003edecrypt($decryptor);\n```\n\n\u003e :warning: WARNING\n\u003e\n\u003e Always make sure that the algorithm specified in the `\u003cxenc:EncryptionMethod\u003e`\n\u003e element is a block cipher algorithm. Only in that case the library will\n\u003e attempt to decrypt using the shared secret encryption scheme. The\n\u003e `SimpleSAML\\XMLSecurity\\Constants::$BLOCK_CIPHER_ALGORITHMS` associative\n\u003e array contains as keys all the identifiers of block ciphers supported by this\n\u003e library.\n\nAlternatively, if your application uses asymmetric encryption, you will have to\nuse an appropriate decryptor instantiated with your private key in order to\ndecrypt your objects:\n\n```php\nuse SimpleSAML\\XMLSecurity\\Alg\\KeyTransport\\KeyTransportAlgorithmFactory;\nuse SimpleSAML\\XMLSecurity\\Key\\PrivateKey;\n\n$decryptor = (new KeyTransportAlgorithmFactory())-\u003egetAlgorithm(\n    $myEncryptedObject-\u003egetEncryptedKey()-\u003egetEncryptionMethod()-\u003egetAlgorithm(),\n    PrivateKey::fromFile('/path/to/private-key.pem')\n);\n$myObject = $myEncryptedObject-\u003edecrypt($decryptor);\n```\n\nOne last note: you may have noticed the `getBlacklistedAlgorithms()` and\n`getEncryptionBackend()` methods that you are required to implement when using\n`EncryptedElementTrait`. These methods are needed because of asymmetric\nencryption support. Since the library will have to create a block cipher\ndecryptor with the session key, the user does not control that decryptor and\ntherefore won't be able to specify directly neither the algorithms to forbid\nnor the encryption backend to use. Hence the need of these two methods, which\nwill allow the trait to modify any of those parameters for the decryptor it\nwill build. If you just want to use the default values, just implement them to\nreturn `null`. However, if you want to customise the algorithms you accept\nand/or the backend to use, then you will have to return the desired values in\nthose methods.\n\n### Encrypting objects\n\nIf you want to support decrypting objects, it is likely that you also want to\nencrypt them in the first place. Doing so is as simple as implementing the\n`SimpleSAML\\XMLSecurity\\XML\\EncryptableElementInterface`:\n\n```php\nuse SimpleSAML\\XML\\AbstractElement;\nuse SimpleSAML\\XMLSecurity\\XML\\EncryptableElementInterface;\nuse SimpleSAML\\XMLSecurity\\XML\\EncryptableElementTrait;\n\nclass MyObject extends AbstractElement\n  implements EncryptableElementInterface\n{\n    use EncryptableElementTrait;\n\n\n    public function getBlacklistedAlgorithms(): ?array\n    {\n        // return an array with the algorithms you don't want to allow to be used\n    }\n    \n    \n    public function getEncryptionBackend(): ?EncryptionBackend\n    {\n        // return the encryption backend you want to use,\n        // or null if you are fine with the default\n    }\n}\n```\n\nThat's it. Easy, isn't it? In this case, the `encrypt()` method is provided\ndirectly by `SimpleSAML\\XMLSecurity\\XML\\EncryptableElementTrait`, since its\nreturn value will always be a `SimpleSAML\\XMLSecurity\\XML\\xenc\\EncryptedData`\nobject. Again, you have to implement a couple of abstract methods required by\nthe trait in order to tell it what algorithms are supported and what backend\nit should use in case of asymmetric encryption.\n\nNow, we just need to actually encrypt our objects. If our application uses\nshared key encryption, we just need to create an appropriate encryptor with\na symmetric key:\n\n```php\nuse SimpleSAML\\XMLSecurity\\Constants as C;\nuse SimpleSAML\\XMLSecurity\\Alg\\Encryption\\EncryptionAlgorithmFactory;\nuse SimpleSAML\\XMLSecurity\\Key\\SymmetricKey;\n\n$encryptor = (new EncryptionAlgorithmFactory())-\u003egetAlgorithm(\n    C::BLOCK_ENC_...,\n    new SymmetricKey('MY SHARED SECRET')\n);\n$myEncryptedObject = $myObject-\u003eencrypt($encryptor)\n```\n\nIf, on the contrary, we want to use an asymmetric encryption scheme, our\nencryptor will need to implement a _key transport_ algorithm, and use a\npublic key:\n\n```php\nuse SimpleSAML\\XMLSecurity\\Constants as C;\nuse SimpleSAML\\XMLSecurity\\Alg\\KeyTransport\\KeyTransportAlgorithmFactory;\nuse SimpleSAML\\XMLSecurity\\Key\\PublicKey;\n\n$encryptor = (new KeyTransportAlgorithmFactory())-\u003egetAlgorithm(\n    C::KEY_TRANSPORT_...,\n    PublicKey::fromFile('/path/to/public-key.pem')\n);\n$myEncryptedObject = $myObject-\u003eencrypt($encryptor);\n```\n\nThat will cover most needs. In general, **asymmetric encryption** will be\npreferred for most applications, as secret management is a difficult problem to\ntackle. If you need to implement a different encryption scheme than the two\nsupported here, you will have to implement the `encrypt()` method yourself.\n\n## Extending the library\n\nNot available yet.\n\n## Keys for testing purposes\n\nAll encrypted keys use '1234' as passphrase.\n\nThe following keys are available:\n\n- signed      - A CA-signed certificate\n- other       - Another CA-signed certificate\n- selfsigned  - A self-signed certificate\n- broken      - A file with a broken PEM-structure\n                (all spaces are removed from the headers)\n- corrupted   - This looks like a proper certificate\n                (every first \u0026 last character of every line has been swapped)\n- expired     - This CA-signed certificate expires the moment it is generated\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimplesamlphp%2Fxml-security","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimplesamlphp%2Fxml-security","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimplesamlphp%2Fxml-security/lists"}