Neverending Plethora of Modules

    @jielu/xmldsigjs
    TypeScript icon, indicating that this package has built-in type declarations

    2.1.5 • Public • Published

    XMLDSIGjs

    license CircleCI Coverage Status npm version

    NPM

    XMLDSIG is short for "XML Digital Signature". This library aims to provide an implementation of XMLDSIG in Typescript/Javascript that uses Web Crypto for cryptographic operations so it can be used both in browsers and in Node.js (when used with a polyfill like node-webcrypto-ossl or node-webcrypto-p11).

    INSTALLING

    npm install xmldsigjs
    

    The npm module has build folder with the following files:

    Name Size Description
    index.js 105 Kb CJS module with external modules
    index.es.js 100 Kb ES module with external modules
    xmldsig.js 872 Kb IIFE bundle module
    xmldsig.min.js 398 Kb minified IIFE bundled module

    COMPATABILITY

    CRYPTOGRAPHIC ALGORITHM SUPPORT

    SHA1 SHA2-256 SHA2-384 SHA2-512
    RSASSA-PKCS1-v1_5 X X X X
    RSA-PSS X X X X
    ECDSA X X X X
    HMAC X X X X

    CANONICALIZATION ALGORITHM SUPPORT

    • XmlDsigC14NTransform
    • XmlDsigC14NWithCommentsTransform
    • XmlDsigExcC14NTransform
    • XmlDsigExcC14NWithCommentsTransform
    • XmlDsigEnvelopedSignatureTransform
    • XmlDsigBase64Transform

    PLATFORM SUPPORT

    XMLDSIGjs works with any browser that supports Web Crypto. Since node does not have Web Crypto you will need a polyfill on this platform, for this reason the npm package includes node-webcrypto-ossl; browsers do not need this dependency and in those cases though it will be installed it will be ignored.

    If 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.

    To use node-webcrypto-ossl you need to specify you want to use it, that looks like this:

    var xmldsigjs = require("xmldsigjs");
    var WebCrypto = require("node-webcrypto-ossl");
    
    xmldsigjs.Application.setEngine("OpenSSL", new WebCrypto());

    The 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:

    var xmldsigjs = require("xmldsigjs");
    var WebCrypto = require("node-webcrypto-p11");
    
    xmldsigjs.Application.setEngine("PKCS11", new WebCrypto({
        library: "/path/to/pkcs11.so",
    	name: "Name of PKCS11 lib",
    	slot: 0,
        sessionFlags: 4, // SERIAL_SESSION
    	pin: "token pin"
    }));

    WARNING

    Using XMLDSIG is a bit like running with scissors so use it cautiously. That said it is needed for interoperability with a number of systems, for this reason, we have done this implementation.

    Usage

    Sign

    SignedXml.Sign(algorithm: Algorithm, key: CryptoKey, data: Document, options?: OptionsSign): PromiseLike<Signature>;

    Parameters

    Name Description
    algorithm Signing Algorithm
    key Signing Key
    data XML document which must be signed
    options Additional options

    Options

    interface OptionsSign {
        /**
         * Id of Signature
         */
        id?: string 
        /**
         * Public key for KeyInfo block
         */
        keyValue?: CryptoKey;
        /**
         * List of X509 Certificates
         */
        x509?: string[];
        /**
         * List of Reference
         * Default is Reference with hash alg SHA-256 and exc-c14n transform  
         */
        references?: OptionsSignReference[];
    }
    
    interface OptionsSignReference {
        /**
         * Id of Reference
         */
        id?: string;
        uri?: string;
        /**
         * Hash algorithm
         */
        hash: AlgorithmIdentifier;
        /**
         * List of transforms
         */
        transforms?: OptionsSignTransform[];
    }
    
    type OptionsSignTransform = "enveloped" | "c14n" | "exc-c14n" | "c14n-com" | "exc-c14n-com" | "base64";

    Verify

    Verify(key?: CryptoKey): PromiseLike<boolean>;

    Parameters

    Name Description
    key Verifying Key. Optional. If key not set it looks for keys in KeyInfo element of Signature.

    EXAMPLES

    For Sign/Verify operations you will need to use a Web Crypto CryptoKey. You can see examples for an example of how to do that.

    Initiating in NodeJs

    "use strict";
    
    const WebCrypto = require("node-webcrypto-ossl");
    const crypto = new WebCrypto();
    const XmlDSigJs = require("xmldsigjs");
    
    XmlDSigJs.Application.setEngine("OpenSSL", crypto);

    Initiating in Browser

    Get the latest version form unpkg.com/xmldsigjs

    <script src="https://unpkg.com/xmldsigjs@<version>/build/xmldsig.js"></script>

    Creating a XMLDSIG Signature

    "use strict";
    
    let signature = new XmlDSigJs.SignedXml();
    
    signature.Sign(                                  // Signing document
        { name: "RSASSA-PKCS1-v1_5" },                        // algorithm 
        keys.privateKey,                                      // key 
        XmlDSigJs.Parse(xml),                                 // document
        {                                                     // options
            keyValue: keys.publicKey,
            references: [
                { hash: "SHA-512", transforms: ["enveloped", "c14n"] },
            ]
        })
        .then(() => {
            console.log(signature.toString());       // <xml> document with signature
        })
        .catch(e => console.log(e));

    Checking a XMLDSIG Signature

    let doc = XmlDSigJs.Parse(xml);
    let signature = doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Signature");
    
    let signedXml = new XmlDSigJs.SignedXml(doc);
    signedXml.LoadXml(signature[0]);
    
    signedXml.Verify()
        .then(res => {
            console.log("Signature status:", res);       // Signature status: true
        })
        .catch(e => console.log(e));

    Browser Verify Example

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8"/>
        <title>XMLDSIGjs Verify Sample</title>
    </head>
    
    <body>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.7.0/polyfill.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/asmCrypto/2.3.2/asmcrypto.all.es5.min.js"></script>
        <script src="https://cdn.rawgit.com/indutny/elliptic/master/dist/elliptic.min.js"></script>
        <script src="https://unpkg.com/webcrypto-liner@1.1.2/build/webcrypto-liner.shim.min.js"></script>
        <script src="https://unpkg.com/xmldsigjs@2.0.27/build/xmldsig.js"></script>
        <script type="text/javascript">
            fetch("signature.xml")
            .then(function(response) {
                return response.text();
            }).then(function(body) {
                var xmlString = body;
    
                var signedDocument = XmlDSigJs.Parse(xmlString);
                var xmlSignature = signedDocument.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Signature");
    
                var signedXml = new XmlDSigJs.SignedXml(signedDocument);
                signedXml.LoadXml(xmlSignature[0]);
                signedXml.Verify()
                .then(function (res) {
                    console.log((res ? "Valid" : "Invalid") + " signature");
                })
                .catch(function (e) {
                    console.error(e);
                });
            })
        </script>
    </body>
    </html>

    TESTING

    In NodeJS:

    npm test
    

    In the browser

    To run the browser test you need to run a test server, from the test directory run:

    npm start
    

    And the then browse to `http://localhost:3000'.

    THANKS AND ACKNOWLEDGEMENT

    This project takes inspiration (style, approach, design and code) from both the Mono System.Security.Cryptography.Xml implementation as well as xml-crypto.

    RELATED

    Install

    npm i @jielu/xmldsigjs

    DownloadsWeekly Downloads

    2

    Version

    2.1.5

    License

    MIT

    Unpacked Size

    1.31 MB

    Total Files

    49

    Last publish

    Collaborators

    • jielu