This is demo on how to do client authentication with certificates, mTLS or mutual TLS - as opposed to username and passwords with out of the box (OOTB) Node.js.
This demo has a server with two clients:
- "Valid" who has a server-signed trusted certificate
- "Invalid" who has an invalid self-signed certificate
Based on the following tutorials:
-
Authentication using HTTPS client certificates Author: Andras Sevcsik-Zajácz, Web technology enthusiast
-
HTTPS Authorized Certs with Node.js Author: Anders Brownworth, Rethinking money @CirclePay | Co-taught the Blockchain class at MIT
First install required dependencies with npm install. Then the demo works as follows:
We start a sever that by default only accepts requests authenticated by client certificates
npm run server
You can test this is working by opening https://localhost:8443/token in your browser.
$ npm run valid-client
> node ./client/valid.js
$ npm run invalid-client
> node ./client/invalid.js
- CN: localhost
- O: Client Certificate Demo
openssl req \
-x509 \
-newkey rsa:4096 \
-keyout server/keys/server_key.pem \
-out server/keys/server_cert.pem \
-nodes \
-days 365 \
-subj "/CN=localhost/O=Client\ Certificate\ Demo"This command shortens following three commands:
openssl genrsaopenssl reqopenssl x509
which generates two files:
server_cert.pemserver_key.pem
For demo, two users are created:
- Valid, who has a valid certificate, signed by the server
- Invalid, who creates own certificate, self-signed
We create a certificate for Valid.
- sign Certificate Signing Request (CSR)...
- with our server key via
-CA server/keys/server_cert.pemand-CAkey server/keys/server_key.pemflags - and save results as certificate
# generate server-signed (valid) certificate
openssl req \
-newkey rsa:4096 \
-keyout client/keys/valid_key.pem \
-out client/keys/valid_csr.pem \
-nodes \
-days 365 \
-subj "/CN=Valid"
# sign with server_cert.pem
openssl x509 \
-req \
-in client/keys/valid_csr.pem \
-CA server/keys/server_cert.pem \
-CAkey server/keys/server_key.pem \
-out client/keys/valid_cert.pem \
-set_serial 01 \
-days 365A certificate without our server key.
# generate self-signed (invalid) certificate
openssl req \
-newkey rsa:4096 \
-keyout client/keys/invalid_key.pem \
-out client/keys/invalid_csr.pem \
-nodes \
-days 365 \
-subj "/CN=Invalid"
# sign with invalid_csr.pem
openssl x509 \
-req \
-in client/keys/invalid_csr.pem \
-signkey client/keys/invalid_key.pem \
-out client/keys/invalid_cert.pem \
-days 365- Let's Encrypt is a "free, automated, and open" Certificate Authority
- PEM: Privacy Enhanced Mail is a Base64 encoded DER certificate
| Command | Documentation | Description |
|---|---|---|
genrsa |
Docs | Generates an RSA private key |
req |
Docs | Primarily creates and processes certificate requests in PKCS#10 format. It can additionally create self signed certificates for use as root CAs for example. |
x509 |
Docs | The x509 command is a multi purpose certificate utility. It can be used to display certificate information, convert certificates to various forms, sign certificate requests like a "mini CA" or edit certificate trust settings. |