简体   繁体   中英

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?

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.

The answer is both "yes" and "no". CryptoJS doesn't expose an ASN.1/DER library which is used to encode the certificates. It only exposes cryptographic routines. So you can perform the self signing, but you cannot generate the input data without implementing an ASN.1/DER library on the side.

So in the end CryptoJS only exposes a very limited amount of functionality required to create the certificates. On the other hand, that's probably all the cryptography you're going to need. Although ASN.1/DER encoding is little more than a data format, it's a pretty complex data format and you must have quite a bit of knowledge to get an ASN.1/DER library up and running. ASN.1/DER generation is easier though than parsing.

Still, I would be inclined to say no rather than yes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM