Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Node's crypto Library to Create a Self-signed Certificate?

Is it possible in pure JavaScript (no openssl binary) to use Node's crypto library to generate a self-signed certificate? Here is my script that uses openssl to generate a certificate:

#!/bin/bash
FQDN="*"

# Create a private key
openssl genrsa \
    -out server-key.pem \
    2048

# Create a certificate signing request
openssl req \
    -new \
    -key server-key.pem \
    -out certificate-signing-request.csr \
    -subj "/C=US/ST=StateL=City/O=Full Name/CN=${FQDN}"

# Sign the certificate signing request to create the server certificate
openssl x509 \
    -req -in certificate-signing-request.csr \
    -signkey server-key.pem \
    -out server-certificate.pem \
    -days 36159

I'm curious if this could all be done using JavaScript and the classes and methods available here:

https://nodejs.org/api/crypto.html

If so, what would the code look like to create files above?

like image 864
Kirk Ouimet Avatar asked Jul 25 '15 07:07

Kirk Ouimet


1 Answers

You can't use Node's crypto to generate a certificate, from their API docs there aren't any functions for creating one (they suggest using openSSL). You could certainly sign a certificate but that requires external actions.

What you can do, if you'd like a solution that does all of it in JS (as suggested also by @robertklep), is using a native implementation in JavaScript like Forge.

In this code sample you create a certificate, self-sign it and export it in PEM format. Forge has everything you need for it, so crypto isn't required.

var forge = require('node-forge');
var pki = forge.pki;

// generate a keypair or use one you have already
var keys = pki.rsa.generateKeyPair(2048);

// create a new certificate
var cert = pki.createCertificate();

// fill the required fields
cert.publicKey = keys.publicKey;
cert.serialNumber = '01';
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);

// use your own attributes here, or supply a csr (check the docs)
var attrs = [{
  name: 'commonName',
  value: 'example.org'
}, {
  name: 'countryName',
  value: 'US'
}, {
  shortName: 'ST',
  value: 'Virginia'
}, {
  name: 'localityName',
  value: 'Blacksburg'
}, {
  name: 'organizationName',
  value: 'Test'
}, {
  shortName: 'OU',
  value: 'Test'
}];

// here we set subject and issuer as the same one
cert.setSubject(attrs);
cert.setIssuer(attrs);

// the actual certificate signing
cert.sign(keys.privateKey);

// now convert the Forge certificate to PEM format
var pem = pki.certificateToPem(cert);
console.log(pem);

The process is pretty straighforward with relatively low amounts of code needed. The forge readme lists all other options, like supplying a csr for attributes and extensions instead of doing it all in code.

like image 95
Sosdoc Avatar answered Oct 17 '22 10:10

Sosdoc