selfsigned

repository·master·Indexed 42 days ago

https://github.com/jfromaniello/selfsigned

A Node.js utility for programmatically generating self-signed X.509 certificates and client certificates using native crypto. Version 5.5.0 requires Node.js >= 15.6.0 and provides an asynchronous API to generate PEM-encoded private keys, public keys, and certificates. It supports RSA and Elliptic Curve (EC) keys, custom X.509 extensions, passphrase encryption via AES-256-CBC, and the ability to sign certificates using an existing Certificate Authority (CA).

Tokens
4.1K
Snippets
13
Records
16
Agent score
4%

What's inside selfsigned

  1. Encrypt the private key with a passphrase

    master

    Provide a passphrase in the options to encrypt the generated private key using AES-256-CBC. The resulting private key will be in encrypted PKCS#8 format (-----BEGIN ENCRYPTED PRIVATE KEY-----).

    To use the encrypted key with Node.js https or crypto, you must provide the passphrase during decryption or server setup.

    const https = require('https');
    
    // Use directly with HTTPS server
    https.createServer({
      key: pems.private,
      passphrase: 'my-secret-passphrase',
      cert: pems.cert
    }, app).listen(443);
  2. Sign certificates with an existing CA

    master

    To generate certificates that are trusted by a specific Certificate Authority (e.g., for local development with mkcert), provide the CA's key and certificate in the ca option.

    const fs = require('fs');
    const selfsigned = require('selfsigned');
    
    const pems = await selfsigned.generate([
      { name: 'commonName', value: 'localhost' }
    ], {
      algorithm: 'sha256',
      ca: {
        key: fs.readFileSync('/path/to/ca.key', 'utf8'),
        cert: fs.readFileSync('/path/to/ca.crt', 'utf8')
      }
    });
  3. Migrate from selfsigned v4.x to v5.x

    master

    Version 5.0 introduced several breaking changes that require updates to your implementation:

    1. Async-only API: The generate() function is now asynchronous and returns a Promise. Synchronous generation and callback support have been removed.
    2. Minimum Node.js version: Requires Node.js >= 15.6.0.
    3. Validity Period: The days option has been removed. You must now use notAfterDate to specify the expiration date. If not provided, the default validity is 365 days from notBeforeDate.
    4. Dependencies: The library now uses @peculiar/x509 and pkijs instead of node-forge.
    // v4.x (Old - Synchronous/Callback)
    const pems = selfsigned.generate(attrs, { days: 365 });
    
    selfsigned.generate(attrs, { days: 365 }, function(err, pems) {
      if (err) throw err;
      console.log(pems);
    });
    
    // v5.x (New - Async/Await)
    const pems = await selfsigned.generate(attrs);
    
    // v5.x (New - Custom validity using notAfterDate)
    const notAfter = new Date();
    notAfter.setDate(notAfter.getDate() + 30); // 30 days
    const pemsCustom = await selfsigned.generate(attrs, { notAfterDate: notAfter });
    
    // v5.x (New - Promise .then() syntax)
    selfsigned.generate(attrs)
      .then(pems => console.log(pems))
      .catch(err => console.error(err));
  4. Set a custom validity period for certificates

    master

    Control the certificate's lifespan using notBeforeDate and notAfterDate in the options object.

    // Valid for 30 days using date-fns
    const { addDays } = require('date-fns');
    const pems = await selfsigned.generate(null, {
      notBeforeDate: new Date(),
      notAfterDate: addDays(new Date(), 30)
    });
    
    // Valid for 2 years using vanilla JS
    const notBefore = new Date();
    const notAfter = new Date(notBefore);
    notAfter.setFullYear(notAfter.getFullYear() + 2);
    
    const pems2 = await selfsigned.generate(null, {
      notBeforeDate: notBefore,
      notAfterDate: notAfter
    });
  5. Generate Elliptic Curve (EC) keys

    master

    To use Elliptic Curve cryptography instead of the default RSA, set keyType: 'ec' in the options. You can specify the curve using the curve option.

    Supported Curves:

    • P-256 (default): 128-bit security, fastest.
    • P-384: 192-bit security.
    • P-521: 256-bit security, strongest.
    // Default P-256 curve
    const pems = await selfsigned.generate(null, { keyType: 'ec' });
    
    // P-384 curve
    const pems2 = await selfsigned.generate(null, { keyType: 'ec', curve: 'P-384' });
    
    // P-521 curve with SHA-512
    const pems3 = await selfsigned.generate(null, {
      keyType: 'ec',
      curve: 'P-521',
      algorithm: 'sha512'
    });
  6. Generate a self-signed certificate with generate()

    master

    In version 5.0+, the generate() function is asynchronous and returns a Promise. You must provide an array of attributes (following X.509 standards) to define the certificate subject.

    Output Format: The resolved Promise returns an object containing the PEM-encoded keys and certificate:

    {
      "private": "-----BEGIN PRIVATE KEY-----\n...",
      "public": "-----BEGIN PUBLIC KEY-----\n...",
      "cert": "-----BEGIN CERTIFICATE-----\n...",
      "fingerprint": "XX:XX:XX:..."
    }
    const selfsigned = require('selfsigned');
    
    const attrs = [{ name: 'commonName', value: 'contoso.com' }];
    const pems = await selfsigned.generate(attrs);
    console.log(pems);
  7. Generate client certificates

    master

    To generate client certificates (where the client key is signed by the server key), set clientCertificate: true or provide a detailed configuration object.

    Output: When clientCertificate is enabled, the returned object includes additional fields:

    • clientprivate: The client's private key.
    • clientpublic: The client's public key.
    • clientcert: The client's certificate.

    Customizing Client Certificates: Use an object for the clientCertificate option to control its properties:

    • cn: Common name (default: 'John Doe jdoe123').
    • keyType: 'rsa' or 'ec' (inherits from parent if not specified).
    • keySize: RSA key size (default: 2048).
    • curve: EC curve (default: 'P-256').
    • algorithm: Signature algorithm (inherits from parent or defaults to 'sha1').
    • notBeforeDate / notAfterDate: Validity period.
    // Simple client certificate
    const pems = await selfsigned.generate(null, { clientCertificate: true });
    
    // Custom client certificate
    const pems2 = await selfsigned.generate(null, {
      clientCertificate: {
        cn: 'FooBar',
        keyType: 'rsa',
        keySize: 4096
      }
    });
  8. Use PKCS#7 formatting with selfsigned

    master

    To generate certificates in PKCS#7 format, use the createPkcs7 function from the selfsigned/pkcs7 module. This is provided as a separate module to allow for better tree-shaking in your applications.

    You can use it for standard certificates or specifically for client certificates by setting the clientCertificate: true option in the generate call.

    const selfsigned = require('selfsigned');
    const { createPkcs7 } = require('selfsigned/pkcs7');
    
    // Standard certificate PKCS#7
    const pems = await selfsigned.generate(attrs);
    const pkcs7 = createPkcs7(pems.cert);
    console.log(pkcs7); // PKCS#7 formatted certificate
    
    // Client certificate PKCS#7
    const pemsClient = await selfsigned.generate(null, { clientCertificate: true });
    const clientPkcs7 = createPkcs7(pemsClient.clientcert);
  9. Configure certificate generation options

    master

    The generate(attrs, options) function accepts an optional options object to customize the certificate and key generation.

    Available Options:

    • keyType: 'rsa' (default) or 'ec'.
    • keySize: Size in bits for RSA keys (default: 2048).
    • curve: Elliptic curve for EC keys: 'P-256' (default), 'P-384', or 'P-521'.
    • notBeforeDate: Start of validity (default: new Date()).
    • notAfterDate: End of validity (default: notBeforeDate + 365 days).
    • algorithm: Signature algorithm: 'sha1' (default), 'sha256', 'sha384', or 'sha512'.
    • extensions: Array of custom certificate extensions.
    • clientCertificate: Boolean or options object to generate a client certificate.
    • ca: Object containing { key, cert } to sign the certificate with an existing CA instead of self-signing.
    • passphrase: String to encrypt the private key using AES-256-CBC.
    const pems = await selfsigned.generate(null, {
      keyType: 'rsa',
      keySize: 2048,
      curve: 'P-256',
      notBeforeDate: new Date(),
      notAfterDate: new Date('2026-01-01'),
      algorithm: 'sha256',
      extensions: [{ name: 'basicConstraints', cA: true }],
      clientCertificate: true,
      ca: { key: '...', cert: '...' },
      passphrase: 'secret'
    });
  10. Use existing private and public keys

    master

    Instead of generating a new key pair, you can provide your own existing keys using the keyPair option.

    const pems = await selfsigned.generate(null, {
      keyPair: {
        publicKey: '-----BEGIN PUBLIC KEY-----...',
        privateKey: '-----BEGIN PRIVATE KEY-----...'
      }
    });