{"id":18601551,"url":"https://github.com/peculiarventures/xadesjs","last_synced_at":"2025-04-05T17:05:47.919Z","repository":{"id":40738028,"uuid":"54531436","full_name":"PeculiarVentures/xadesjs","owner":"PeculiarVentures","description":"A pure Typescript/Javascript implementation of XAdES based on XMLDSIGjs. (Keywords: WebCrypto, XMLDSIG, XADES, eIDAS, Trust List, X.509, CRL, OCSP)","archived":false,"fork":false,"pushed_at":"2023-03-07T01:53:29.000Z","size":1798,"stargazers_count":144,"open_issues_count":47,"forks_count":50,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-03-29T16:05:15.567Z","etag":null,"topics":["ades","electronic-signatures","javascript","node-webcrypto-ossl","typescript","web-crypto","webcrypto","xades-bes","xmldsig"],"latest_commit_sha":null,"homepage":"https://xadesjs.com","language":"TypeScript","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/PeculiarVentures.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2016-03-23T04:43:21.000Z","updated_at":"2025-03-07T17:55:17.000Z","dependencies_parsed_at":"2024-06-18T15:33:58.063Z","dependency_job_id":"d81ce57b-8900-44b7-b46f-5920588ddd6b","html_url":"https://github.com/PeculiarVentures/xadesjs","commit_stats":{"total_commits":348,"total_committers":6,"mean_commits":58.0,"dds":0.4913793103448276,"last_synced_commit":"9a26ae9fe56ccff2008e02ccc3c7156df3739504"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeculiarVentures%2Fxadesjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeculiarVentures%2Fxadesjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeculiarVentures%2Fxadesjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeculiarVentures%2Fxadesjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PeculiarVentures","download_url":"https://codeload.github.com/PeculiarVentures/xadesjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369952,"owners_count":20927928,"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":["ades","electronic-signatures","javascript","node-webcrypto-ossl","typescript","web-crypto","webcrypto","xades-bes","xmldsig"],"created_at":"2024-11-07T02:08:43.887Z","updated_at":"2025-04-05T17:05:47.898Z","avatar_url":"https://github.com/PeculiarVentures.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# XAdESjs\r\n\r\n[![license](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/PeculiarVentures/xadesjs/master/LICENSE.md)\r\n[![CircleCI](https://circleci.com/gh/PeculiarVentures/xadesjs.svg?style=svg)](https://circleci.com/gh/PeculiarVentures/xadesjs)\r\n[![Coverage Status](https://coveralls.io/repos/github/PeculiarVentures/xadesjs/badge.svg?branch=master)](https://coveralls.io/github/PeculiarVentures/xadesjs?branch=master)\r\n[![npm version](https://badge.fury.io/js/xadesjs.svg)](https://badge.fury.io/js/xadesjs)\r\n\r\n[![NPM](https://nodei.co/npm/xadesjs.png)](https://nodei.co/npm/xadesjs/)\r\n\r\n\r\n[XAdES](https://en.wikipedia.org/wiki/XAdES) is short for \"XML Advanced Electronic Signatures\", it is a superset of XMLDSIG. This library aims to provide an implementation of XAdES in Typescript/Javascript that is built on [XMLDSIGjs](https://github.com/PeculiarVentures/xmldsigjs).\r\n\r\nSince it is based on [XMLDSIGjs](https://github.com/PeculiarVentures/xmldsigjs) and that library uses Web Crypto for cryptographic operations it can be used both in browsers and in Node.js (when used with a polyfill like [webcrypto](https://github.com/PeculiarVentures/webcrypto), [node-webcrypto-ossl](https://github.com/PeculiarVentures/node-webcrypto-ossl) or [node-webcrypto-p11](https://github.com/PeculiarVentures/node-webcrypto-p11)).\r\n\r\nThere are seven different profiles of XAdES, they are:\r\n- Basic Electronic Signature (XAdES-BES)\r\n- XAdES with Timestamp (XAdES-T)\r\n- XAdES with Complete Validation Data (XAdES-C)\r\n- XAdES with Extended Validation Data (XAdES-X)\r\n- XAdES with Extended Long Term Validation Data (XAdES-X-L)\r\n- XAdES with Archiving Validation Data (XAdES-A)\r\n- XAdES with Explicit policy electronic signatures (XAdES-EPES)\r\n\r\nThey differ slightly based on what is included in the signature:\r\n\r\n|            | Provides Digital Signature | Includes Cryptographic Timestamp | Includes Revocation References | Includes Revocation Data | Allows Secure Timestamp Countersignature |\r\n|------------|----------------------------|----------------------------------|--------------------------------|--------------------------|------------------------------------------|\r\n| **XAdES-BES**  | **Yes**                        | **No**                               | **No**                             | **No**                       | **No**                                       |\r\n| XAdES-EPES | Yes                        | No                               | No                             | No                       | No                                       |\r\n| XAdES-T    | Yes                        | Yes                              | No                             | No                       | No                                       |\r\n| XAdES-C    | Yes                        | Yes                              | Yes                            | No                       | No                                       |\r\n| XAdES-X    | Yes                        | Yes                              | Yes                            | No                       | No                                       |\r\n| XAdES-X-L  | Yes                        | Yes                              | Yes                            | Yes                      | No                                       |\r\n| XAdES-A    | Yes                        | Yes                              | Yes                            | Yes                      | Yes                                      |\r\n\r\n- Only XAdES-BES (in *BOLD*) is fully supported by XAdESjs. For the other variants can be created, decoded and verified but the caller must do the construction and policy to ensure compliant messages on their own.\r\n\r\n## INSTALLING\r\n\r\n```\r\nnpm install xadesjs\r\n```\r\n\r\nThe npm module has a `dist` folder with the following files:\r\n\r\n| Name            | Size   | Description                                    |\r\n|-----------------|--------|------------------------------------------------|\r\n| index.js        | 105 Kb | UMD module with external modules. Has comments |\r\n| xades.js        | 803 Kb | UMD bundle module. Has comments                |\r\n| xades.min.js    | 296 Kb | minified UMD bundle module                     |\r\n\r\nThere is also a `lib` folder with an ES2015 JS file which you can use with `rollup` bundler.\r\n\r\n## COMPATABILITY\r\n\r\n### CRYPTOGRAPHIC ALGORITHM SUPPORT\r\n\r\n| Name              | SHA1 | SHA2-256 | SHA2-384 | SHA2-512 |\r\n|-------------------|------|----------|----------|----------|\r\n| RSASSA-PKCS1-v1_5 | X    | X        | X        | X        |\r\n| RSA-PSS           | X    | X        | X        | X        |\r\n| ECDSA             | X    | X        | X        | X        |\r\n| HMAC              | X    | X        | X        | X        |\r\n\r\n### CANONICALIZATION ALGORITHM SUPPORT\r\n\r\n- XmlDsigC14NTransform\r\n- XmlDsigC14NWithCommentsTransform\r\n- XmlDsigExcC14NTransform\r\n- XmlDsigExcC14NWithCommentsTransform\r\n- XmlDsigEnvelopedSignatureTransform\r\n- XmlDsigBase64Transform\r\n\r\n\r\n### PLATFORM SUPPORT\r\n\r\nXAdESjs works with any browser that suppports Web Crypto. Since node does not have Web Crypto you will need a polyfill on this platform, for this reason the npm package includes [webcrypto](https://github.com/PeculiarVentures/webcrypto); browsers do not need this dependency and in those cases though it will be installed it will be ignored.\r\n\r\nIf you need to use a Hardware Security Module we have also created a polyfill for Web Crypto that supports PKCS #11. Our polyfill for this is [node-webcrypto-p11](https://github.com/PeculiarVentures/node-webcrypto-p11).\r\n\r\nTo use [node-webcrypto-ossl](https://github.com/PeculiarVentures/node-webcrypto-ossl) you need to specify you want to use it, that looks like this:\r\n\r\n```javascript\r\nvar xadesjs = require(\"./built/xades.js\");\r\nvar { Crypto } = require(\"@peculiar/webcrypto\");\r\n\r\nxadesjs.Application.setEngine(\"NodeJS\", new Crypto());\r\n```\r\n\r\nThe [node-webcrypto-p11](https://github.com/PeculiarVentures/node-webcrypto-p11) polyfill will work the same way. The only difference is that you have to specify the details about your PKCS #11 device when you instansiate it:\r\n\r\n```javascript\r\nvar xadesjs = require(\"./built/xades.js\");\r\nvar WebCrypto = require(\"node-webcrypto-p11\").WebCrypto;\r\n\r\nxadesjs.Application.setEngine(\"PKCS11\", new WebCrypto({\r\n    library: \"/path/to/pkcs11.so\",\r\n\tname: \"Name of PKCS11 lib\",\r\n\tslot: 0,\r\n    sessionFlags: 2 | 4, // RW_SESSION | SERIAL_SESSION\r\n\tpin: \"token pin\"\r\n}));\r\n```\r\n\r\n## WARNING\r\n\r\n**Using XMLDSIG is a bit like running with scissors, that said it is needed for interoperability with a number of systems, for this reason, we have done this implementation.**\r\n\r\n## Usage\r\n\r\n### Sign\r\n\r\n```typescript\r\nSignedXml.Sign(algorithm: Algorithm, key: CryptoKey, data: Document, options?: OptionsXAdES): PromiseLike\u003cSignature\u003e;\r\n```\r\n\r\n__Parameters__\r\n\r\n| Name          | Description                                                             |\r\n|:--------------|:------------------------------------------------------------------------|\r\n| algorithm     | Signing [Algorithm](https://www.w3.org/TR/WebCryptoAPI/#algorithms)     |\r\n| key           | Signing [Key](https://www.w3.org/TR/WebCryptoAPI/#cryptokey-interface)  |\r\n| data          | XML document which must be signed                                       |\r\n| options       | Additional options                                                      |\r\n\r\n#### Options\r\n```typescript\r\ninterface OptionsXAdES {\r\n    /**\r\n     * Public key for KeyInfo block\r\n     */\r\n    keyValue?: CryptoKey;\r\n    /**\r\n     * List of X509 Certificates\r\n     */\r\n    x509?: string[];\r\n    /**\r\n     * List of Reference\r\n     * Default is Reference with hash alg SHA-256 and exc-c14n transform  \r\n     */\r\n    references?: OptionsSignReference[];\r\n\r\n    // Signed signature properties\r\n\r\n    signingCertificate?: string;\r\n    signingTime?: OptionsSigningTime;\r\n    policy?: OptionsPolicyId;\r\n    productionPlace?: OptionsProductionPlace;\r\n    signerRole?: OptionsSignerRole;\r\n}\r\n\r\ninterface OptionsSignReference {\r\n    /**\r\n     * Id of Reference\r\n     */\r\n    id?: string;\r\n    uri?: string;\r\n    /**\r\n     * Hash algorithm\r\n     */\r\n    hash: AlgorithmIdentifier;\r\n    /**\r\n     * List of transforms\r\n     */\r\n    transforms?: OptionsSignTransform[];\r\n}\r\n\r\ntype OptionsSignTransform = \"enveloped\" | \"c14n\" | \"exc-c14n\" | \"c14n-com\" | \"exc-c14n-com\" | \"base64\";\r\n\r\ninterface OptionsSigningTime {\r\n    value?: Date;\r\n    format?: string;\r\n}\r\n\r\ninterface OptionsSignerRole {\r\n    claimed?: string[];\r\n    certified?: string[];\r\n}\r\n\r\ninterface OptionsProductionPlace {\r\n    city?: string;\r\n    state?: string;\r\n    code?: string;\r\n    country?: string;\r\n}\r\n\r\ninterface OptionsPolicyId {\r\n}\r\n```\r\n\r\n### Verify\r\n\r\n```typescript\r\nVerify(key?: CryptoKey): PromiseLike\u003cboolean\u003e;\r\n```\r\n\r\n__Parameters__\r\n\r\n| Name          | Description                                                             |\r\n|:--------------|:------------------------------------------------------------------------|\r\n| key           | Verifying [Key](https://www.w3.org/TR/WebCryptoAPI/#cryptokey-interface). Optional. If key not set it looks for keys in KeyInfo element of Signature.  |\r\n\r\n## EXAMPLES\r\n\r\n### Create XAdES-BES Signature\r\n\r\n#### In Node\r\n\r\n```javascript\r\nvar xadesjs = require(\"xadesjs\");\r\nvar { Crypto } = require(\"@peculiar/webcrypto\");\r\n\r\nxadesjs.Application.setEngine(\"NodeJS\", new Crypto());\r\n\r\n// Generate RSA key pair\r\nvar privateKey, publicKey;\r\nxadesjs.Application.crypto.subtle.generateKey(\r\n    {\r\n        name: \"RSASSA-PKCS1-v1_5\",\r\n        modulusLength: 1024, //can be 1024, 2048, or 4096,\r\n        publicExponent: new Uint8Array([1, 0, 1]),\r\n        hash: { name: \"SHA-1\" }, //can be \"SHA-1\", \"SHA-256\", \"SHA-384\", or \"SHA-512\"\r\n    },\r\n    false, //whether the key is extractable (i.e. can be used in exportKey)\r\n    [\"sign\", \"verify\"] //can be any combination of \"sign\" and \"verify\"\r\n)\r\n    .then(function (keyPair) {\r\n        // Push ganerated keys to global variable\r\n        privateKey = keyPair.privateKey;\r\n        publicKey = keyPair.publicKey;\r\n\r\n        // Call sign function\r\n        var xmlString = '\u003cplayer bats=\"left\" id=\"10012\" throws=\"right\"\u003e\\n\\t\u003c!-- Here\\'s a comment --\u003e\\n\\t\u003cname\u003eAlfonso Soriano\u003c/name\u003e\\n\\t\u003cposition\u003e2B\u003c/position\u003e\\n\\t\u003cteam\u003eNew York Yankees\u003c/team\u003e\\n\u003c/player\u003e';\r\n        return SignXml(xmlString, keyPair, { name: \"RSASSA-PKCS1-v1_5\", hash: { name: \"SHA-1\" } });\r\n    })\r\n    .then(function (signedDocument) {\r\n        console.log(\"Signed document:\\n\\n\", signedDocument);\r\n    })\r\n    .catch(function (e) {\r\n        console.error(e);\r\n    });\r\n\r\n\r\nfunction SignXml(xmlString, keys, algorithm) {\r\n    return Promise.resolve()\r\n        .then(() =\u003e {\r\n            var xmlDoc = xadesjs.Parse(xmlString);\r\n            var signedXml = new xadesjs.SignedXml();\r\n\r\n            return signedXml.Sign(               // Signing document\r\n                algorithm,                              // algorithm\r\n                keys.privateKey,                        // key\r\n                xmlDoc,                                 // document\r\n                {                                       // options\r\n                    keyValue: keys.publicKey,\r\n                    references: [\r\n                        { hash: \"SHA-256\", transforms: [\"enveloped\"] }\r\n                    ],\r\n                    productionPlace: {\r\n                        country: \"Country\",\r\n                        state: \"State\",\r\n                        city: \"City\",\r\n                        code: \"Code\",\r\n                    },\r\n                    signingCertificate: \"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\"\r\n                })\r\n            })\r\n            .then(signature =\u003e signature.toString());\r\n}\r\n```\r\n\r\n#### In the browser\r\n\r\n```html\r\n\u003c!DOCTYPE html\u003e\r\n\u003chtml\u003e\r\n\r\n\u003chead\u003e\r\n    \u003cmeta charset=\"utf-8\" /\u003e\r\n    \u003ctitle\u003eXADESJS Signature Sample\u003c/title\u003e\r\n\u003c/head\u003e\r\n\r\n\u003cbody\u003e\r\n    \u003cpre id=\"signature\"\u003e\u003ccode\u003e\u003c/code\u003e\u003c/pre\u003e\r\n    \u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.7.0/polyfill.min.js\"\u003e\u003c/script\u003e\r\n    \u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/asmCrypto/2.3.2/asmcrypto.all.es5.min.js\"\u003e\u003c/script\u003e\r\n    \u003cscript src=\"https://cdn.rawgit.com/indutny/elliptic/master/dist/elliptic.min.js\"\u003e\u003c/script\u003e\r\n    \u003cscript src=\"https://unpkg.com/webcrypto-liner@1.1.2/build/webcrypto-liner.shim.min.js\"\u003e\u003c/script\u003e\r\n    \u003cscript src=\"https://unpkg.com/xadesjs@2.0.16/build/xades.js\"\u003e\u003c/script\u003e\r\n    \u003cscript type=\"text/javascript\"\u003e\r\n        // Generate RSA key pair\r\n        var privateKey, publicKey;\r\n        window.crypto.subtle.generateKey(\r\n            {\r\n                name: \"ECDSA\",\r\n                namedCurve: \"P-256\"\r\n            },\r\n            false, //whether the key is extractable (i.e. can be used in exportKey)\r\n            [\"sign\", \"verify\"] //can be any combination of \"sign\" and \"verify\"\r\n        )\r\n            .then(function (keyPair) {\r\n                // Push ganerated keys to global variable\r\n                privateKey = keyPair.privateKey;\r\n                publicKey = keyPair.publicKey;\r\n                // Call sign function\r\n                var xmlString = '\u003cplayer bats=\"left\" id=\"10012\" throws=\"right\"\u003e\\n\\t\u003c!-- Here\\'s a comment --\u003e\\n\\t\u003cname\u003eAlfonso Soriano\u003c/name\u003e\\n\\t\u003cposition\u003e2B\u003c/position\u003e\\n\\t\u003cteam\u003eNew York Yankees\u003c/team\u003e\\n\u003c/player\u003e';\r\n                return SignXml(xmlString, keyPair, { name: \"ECDSA\", hash: { name: \"SHA-1\" } });\r\n            })\r\n            .then(function (signedDocument) {\r\n                document.getElementById(\"signature\").textContent = signedDocument;\r\n                console.log(\"Signed document:\\n\\n\", signedDocument);\r\n            })\r\n            .catch(function (e) {\r\n                console.error(e);\r\n            });\r\n\r\n        function SignXml(xmlString, keys, algorithm) {\r\n            var signedXml;\r\n            return Promise.resolve()\r\n                .then(() =\u003e {\r\n                    var xmlDoc = XAdES.Parse(xmlString);\r\n                    signedXml = new XAdES.SignedXml();\r\n\r\n                    return signedXml.Sign(               // Signing document\r\n                        algorithm,                              // algorithm\r\n                        keys.privateKey,                        // key\r\n                        xmlDoc,                                 // document\r\n                        {                                       // options\r\n                            keyValue: keys.publicKey,\r\n                            references: [\r\n                                { hash: \"SHA-256\", transforms: [\"enveloped\"] }\r\n                            ],\r\n                            productionPlace: {\r\n                                country: \"Country\",\r\n                                state: \"State\",\r\n                                city: \"City\",\r\n                                code: \"Code\",\r\n                            },\r\n                            signerRole: {\r\n                                claimed: [\"Some role\"]\r\n                            }\r\n                        })\r\n                })\r\n                .then(() =\u003e signedXml.toString());\r\n        }\r\n    \u003c/script\u003e\r\n\u003c/body\u003e\r\n\r\n\u003c/html\u003e\r\n```\r\n\r\n### Check XAdES-BES Signature\r\n\r\n#### In Node\r\n\r\n```js\r\nvar XAdES = require(\"xadesjs\");\r\nvar { Crypto } = require(\"@peculiar/webcrypto\");\r\n\r\nXAdES.Application.setEngine(\"NodeJS\", new Crypto());\r\n\r\nvar fs = require(\"fs\");\r\nvar xmlString = fs.readFileSync(\"some.xml\",\"utf8\");\r\n\r\nvar signedDocument = XAdES.Parse(xmlString, \"application/xml\");\r\nvar xmlSignature = signedDocument.getElementsByTagNameNS(\"http://www.w3.org/2000/09/xmldsig#\", \"Signature\");\r\n\r\nvar signedXml = new xadesjs.SignedXml(signedDocument);\r\nsignedXml.LoadXml(xmlSignature[0]);\r\nsignedXml.Verify()\r\n    .then(res =\u003e {\r\n        console.log((res ? \"Valid\" : \"Invalid\") + \" signature\");\r\n    })\r\n    .catch(function (e) {\r\n        console.error(e);\r\n    });\r\n```\r\n\r\n#### In the browser\r\n\r\n```html\r\n\u003c!DOCTYPE html\u003e\r\n\u003chtml\u003e\r\n\r\n\u003chead\u003e\r\n    \u003cmeta charset=\"utf-8\" /\u003e\r\n    \u003ctitle\u003eXADESJS Signature Sample\u003c/title\u003e\r\n\u003c/head\u003e\r\n\r\n\u003cbody\u003e\r\n    \u003cpre id=\"signature\"\u003e\u003ccode\u003e\u003c/code\u003e\u003c/pre\u003e\r\n    \u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.7.0/polyfill.min.js\"\u003e\u003c/script\u003e\r\n    \u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/asmCrypto/2.3.2/asmcrypto.all.es5.min.js\"\u003e\u003c/script\u003e\r\n    \u003cscript src=\"https://cdn.rawgit.com/indutny/elliptic/master/dist/elliptic.min.js\"\u003e\u003c/script\u003e\r\n    \u003cscript src=\"https://unpkg.com/webcrypto-liner@1.1.2/build/webcrypto-liner.shim.min.js\"\u003e\u003c/script\u003e\r\n    \u003cscript src=\"https://unpkg.com/xadesjs@2.0.16/build/xades.js\"\u003e\u003c/script\u003e\r\n    \u003cscript type=\"text/javascript\"\u003e\r\n        \"use strict\";\r\n        fetch(\"https://cdn.rawgit.com/PeculiarVentures/xadesjs/master/test/static/valid_signature.xml\")\r\n            .then(response =\u003e response.text())\r\n            .then(body =\u003e {\r\n                var xmlString = body;\r\n\r\n                var signedDocument = XAdES.Parse(xmlString);\r\n                var xmlSignature = signedDocument.getElementsByTagNameNS(\"http://www.w3.org/2000/09/xmldsig#\", \"Signature\");\r\n\r\n                var signedXml = new xadesjs.SignedXml(signedDocument);\r\n                signedXml.LoadXml(xmlSignature[0]);\r\n                signedXml.Verify()\r\n                    .then(function (signedDocument) {\r\n                        alert((res ? \"Valid\" : \"Invalid\") + \" signature\");\r\n                    })\r\n                    .catch(function (e) {\r\n                        alert(e.message);\r\n                    });\r\n            })\r\n    \u003c/script\u003e\r\n\u003c/body\u003e\r\n\r\n\u003c/html\u003e\r\n```\r\n\r\n### XAdES-EPES signature\r\n\r\n```js\r\nconst fs = require(\"fs\");\r\nvar { Crypto } = require(\"@peculiar/webcrypto\");\r\nconst xadesjs = require(\"xadesjs\");\r\nconst { XMLSerializer } = require(\"xmldom\");\r\n\r\n\r\nconst crypto = new Crypto();\r\nxadesjs.Application.setEngine(\"NodeJS\", );\r\n\r\nfunction preparePem(pem) {\r\n    return pem\r\n        // remove BEGIN/END\r\n        .replace(/-----(BEGIN|END)[\\w\\d\\s]+-----/g, \"\")\r\n        // remove \\r, \\n\r\n        .replace(/[\\r\\n]/g, \"\");\r\n}\r\n\r\nfunction pem2der(pem) {\r\n    pem = preparePem(pem);\r\n    // convert base64 to ArrayBuffer\r\n    return new Uint8Array(Buffer.from(pem, \"base64\")).buffer;\r\n}\r\n\r\nasync function main() {\r\n    const hash = \"SHA-256\"\r\n    const alg = {\r\n        name: \"RSASSA-PKCS1-v1_5\",\r\n        hash,\r\n    }\r\n\r\n    // Read cert\r\n    const certPem = fs.readFileSync(\"cert.pem\", { encoding: \"utf8\" });\r\n    const certDer = pem2der(certPem);\r\n\r\n    // Read key\r\n    const keyPem = fs.readFileSync(\"key.pem\", { encoding: \"utf8\" });\r\n    const keyDer = pem2der(keyPem);\r\n    const key = await crypto.subtle.importKey(\"pkcs8\", keyDer, alg, false, [\"sign\"]);\r\n\r\n    // XAdES-EPES\r\n    var xmlString = `\u003cTest\u003e\u003cDocument attr=\"Hello\"/\u003e\u003c/Test\u003e`;\r\n    var xml = xadesjs.Parse(xmlString);\r\n\r\n    var xadesXml = new xadesjs.SignedXml();\r\n    const x509 = preparePem(certPem);\r\n    const signature = await xadesXml.Sign(   // Signing document\r\n        alg,                                    // algorithm\r\n        key,                                    // key\r\n        xml,                                    // document\r\n        {                                       // options\r\n            references: [\r\n                { hash, transforms: [\"c14n\", \"enveloped\"] }\r\n            ],\r\n            policy: {\r\n                hash,\r\n                identifier: {\r\n                    qualifier: \"OIDAsURI\",\r\n                    value: \"quilifier.uri\",\r\n                },\r\n                qualifiers: [\r\n                    {\r\n                        noticeRef: {\r\n                            organization: \"PeculiarVentures\",\r\n                            noticeNumbers: [1, 2, 3, 4, 5]\r\n                        }\r\n                    }\r\n                ]\r\n            },\r\n            productionPlace: {\r\n                country: \"Russia\",\r\n                state: \"Marij El\",\r\n                city: \"Yoshkar-Ola\",\r\n                code: \"424000\",\r\n            },\r\n            signingCertificate: x509\r\n        });\r\n\r\n    // append signature\r\n    xml.documentElement.appendChild(signature.GetXml());\r\n\r\n    // serialize XML\r\n    const oSerializer = new XMLSerializer();\r\n    const sXML = oSerializer.serializeToString(xml);\r\n    console.log(sXML.toString())\r\n}\r\n\r\nmain()\r\n    .catch((err) =\u003e {\r\n        console.error(err);\r\n    });\r\n```\r\n\r\n## TESTING\r\n\r\n### In NodeJS:\r\n\r\n```\r\nnpm test\r\n```\r\n\r\n## THANKS AND ACKNOWLEDGEMENT\r\nThis project takes inspiration (style, approach, design and code) from both the [Mono System.Security.Cryptography.Xml](https://github.com/mono/mono/tree/master/mcs/class/System.Security/System.Security.Cryptography.Xml) implementation as well as [xml-crypto](https://github.com/yaronn/xml-crypto).\r\n\r\n## RELATED\r\n- [xmldsigjs](https://github.com/PeculiarVentures/xmldsigjs)\r\n- [Why XML Security is Broken](https://www.cs.auckland.ac.nz/~pgut001/pubs/xmlsec.txt)\r\n- [ETSI EN 319 132-1 - XML Advanced Electronic Signatures (XAdES)](http://www.etsi.org/deliver/etsi_en/319100_319199/31913201/01.01.00_30/en_31913201v010100v.pdf)\r\n- [ETSI EN 319 132-2 - XML Advanced Electronic Signatures (XAdES)](http://www.etsi.org/deliver/etsi_en/319100_319199/31913202/01.01.00_30/en_31913202v010100v.pdf)\r\n- [XML Signature Syntax and Processing](https://www.w3.org/TR/xmldsig-core/)\r\n- [XML Security Algorithm Cross-Reference](https://tools.ietf.org/html/rfc6931)\r\n- [XMLDSIG HTML Signing Profile](https://www.w3.org/2007/11/h6n/)\r\n- [Canonical XML](https://www.w3.org/TR/xml-c14n)\r\n- [Exclusive XML Canonicalization](https://www.w3.org/TR/xml-exc-c14n/)\r\n- [Internet X.509 Public Key Infrastructure Time-Stamp Protocol](https://www.ietf.org/rfc/rfc3161.txt)\r\n- [XAdESj](https://github.com/luisgoncalves/xades4j)\r\n- [PKIjs](pkijs.org)\r\n- [@peculiar/webcrypto](https://github.com/PeculiarVentures/webcrypto)\r\n- [node-webcrypto-ossl](https://github.com/PeculiarVentures/node-webcrypto-ossl)\r\n- [node-webcrypto-p11](https://github.com/PeculiarVentures/node-webcrypto-p11)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeculiarventures%2Fxadesjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeculiarventures%2Fxadesjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeculiarventures%2Fxadesjs/lists"}