43

I'm writing a proxy support HTTPS-HTTPS proxy. Before i use Python as the main programming language, but i'm interested in node.js now, so i prepare to migrate.

The largest problem i'm facing is that i don't know how to generate CA and other server certificates in node.js. In Python, there is pyOpenSSL which is awesome. I don't find something similar in node.js until now.

Maybe i should use openssl-fork method? But how to handle the interactive operation in openssl.

Thank you.

5 Answers 5

39

Use shell for certificate:

openssl genrsa -out server-key.pem 1024 openssl req -new -key server-key.pem -out server-csr.pem openssl x509 -req -in server-csr.pem -signkey server-key.pem -out server-cert.pem 

Then use them in node.js

var https = require('https'); https.createServer({ key: fs.readFileSync('server-key.pem'), cert: fs.readFileSync('server-cert.pem') }, function (req,res) { ... }) 

EDIT:

You can also give a try to this project in NPM : https://npmjs.org/package/openssl-wrapper

I found it searching the NPM repo : https://npmjs.org/search?q=openssl

I did not tried or checked it myself, but it looks like a way to generate the certificate using node, which is the original question.

var openssl = require('openssl-wrapper'); var password = 'github'; return openssl.exec('genrsa', {des3: true, passout: 'pass:' + password, '2048': false}, function(err, buffer) { console.log(buffer.toString()); }); 

I'd be interested by a feedback. ;)

Sign up to request clarification or add additional context in comments.

2 Comments

I see no harm in wrapping those shell scripts in in exec functions and a spawn function, and using that instead of a whole library
error:0480006C:PEM routines::no start line ERR_OSSL_PEM_NO_START_LINE
38

In case somebody does want to programatically create CSRs from node.js, I have created a nodejs module which uses openssl to create a private key and a CSR.

Edit: Use pem instead. It is much more complete and probably more reliable.

Edit2: Actually, pem is also just a simple wrapper over openssh. For a pure js implementation, look into forge

5 Comments

My module is now totally deprecated. I was only publishing it because I didnt know about pem: npmjs.org/package/pem
pem just spawns openssl.
@andrewrk that's a good thing. High-profile vulnerabilities like heartbleed aside (which never effected node directly), keep security and crypto code as isolated and DRY as possible.
@DavidSouther Node actually links against a fork of the OpenSSL libraries, generally with a more recent version than what is on the hosting system.
node-forge is a life saver! As far as I know, it's the only option if you also need Windows support.
11

node-forge allow that. Nothing to say more. DOES NOT use openssl shell command internally.

https://github.com/digitalbazaar/forge#x509

2 Comments

This one is great. And most important, it does not depend on "open-ssl"
I have also used it for production code and it works like a charm.
1

there is a pure javascript library called "Jsrsasign" to generate CSR certificates.

const r = require("jsrsasign"); const kp = r.KEYUTIL.generateKeypair("RSA", 2048); const csr = r.KJUR.asn1.csr.CSRUtil.newCSRPEM({ subject: {}, sbjpubkey: kp.pubKeyObj, sigalg: "SHA256withRSA", sbjprvkey: kp.prvKeyObj, }); const privateKey = r.KEYUTIL.getPEM(kp.prvKeyObj, "PKCS1PRV"); 

for more docs visit http://kjur.github.io/jsrsasign/

Comments

-3

None of the node libraries seem to support the options I need, so I use the openssl executable.

import { execSync } from 'child_process' import fs from 'fs' import tempy from 'tempy' const extHeader = `authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] ` const shell = cmd => execSync(cmd, { stdio: 'pipe' }) const writeCert = (extFile, outfile) => { const cmd = [ `openssl`, `x509`, `-req`, `-in ssl/my.csr`, `-CA ssl/root-ca.pem`, `-CAkey ssl/root-ca.key`, `-CAserial ssl/root-ca.srl`, `-out ssl/${outfile}`, `-days 1825`, `-sha256`, `-extfile ${extFile}`, `-passin pass:mypassphrase` ] shell(cmd.join(' ')) } const createCert = domains => { const sans = domains.map((d, i) => `DNS.${i + 1} = ${d}`) const ext = extHeader + sans.join('\n') const extFile = tempy.file() fs.writeFileSync(extFile, ext, 'utf-8') writeCert(extFile, 'out.crt') } 

Dependencies:

  • openssl executable
  • yarn add tempy

1 Comment

This code seems incomplete... What is ssl/my.csr, ssl/root-ca.pem, etc.? How to generate them? Why not include the code to generate them in the answer?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.