Socket.io/Node.js and SSL - node.js

I recently bought a SSL certificate from Comodo. They sent me these files:
AddTrustExternalCARoot.crt
PositiveSSLCA2.crt
mydomain.crt
I then created my private key and ca-bundle like so,
openssl genrsa -des3 -out mydomain.key 1024
cat PositiveSSLCA2.crt AddTrustExternalCARoot.crt > mydomain.ca-bundle
This is the code I'm using to put it all together. I get an SSL connection error in Chrome.
var privateKey = fs.readFileSync('./mydomain.key').toString();
var certificate = fs.readFileSync('./mydomain.crt').toString();
var ca = fs.readFileSync('./mydomain.ca-bundle').toString();
var io = require('socket.io').listen(1200, { key:privateKey,cert:certificate,ca:ca });

You generate your private key before you are issued a certificate.
A certificate is created when a CA signs the public key that goes with a particular private key. You generate a private key, then you create a CSR which includes the public key. The CA sends you back a certificate.
You must have generated a private key at some point before you got a certificate – you have to use that. If you try to use a private key that you generate after the certificate is issued, it will obviously not match the public key in your certificate.
Also, node's tls module cannot parse certificate bundles. You have to pass each certificate separately in an array.
{
key: fs.readFileSync('mydomain.key'),
cert: fs.readFileSync('mydomain.crt'),
ca: [ fs.readFileSync('AddTrustExternalCARoot.crt'), fs.readFileSync('PositiveSSLCA2.crt') ]
}
The docs have more detail.

Related

Cannot get Client Certificate to work in HTTP Action of Logic App

I am trying to add a HTTP Action that uses Client Certificate authentication to a logic App
When I specify the PFX file that I have generated, I get an error stating
The provided authentication certificate is missing the private key. The private key is required to sign the request.
I am using the portal directly not code
I do have the private key
How do I specify this?
Paul
The provided authentication certificate is missing the private key. The private key is required to sign the request.
You are receiving this error because it is missing a private key. You cannot use Client Certificates for authentication without a private key.
On the Client, the Client Certificates must have a Private Key. If absent, then the certificate is ignored. For more information on this, you can refer Here
While Client certificate Import/Export you need to check the box which will provide us the private key.
Alternate:
Sometimes .pfx gile will not work directly. Use OpenSSL to convert them to a .pem, then back to a pfx to get it to work:
openssl pkcs12 -in certificate.pfx -out certificate.pem
openssl pkcs12 -in certificate.pem -export -out certificate2.pfx
The pfx file will work within Azure logic apps when converted to a base64 string. When the pfx file is imported into the Certificates MMC try exporting again and it works.
REFERENCES:
Call service endpoints by using HTTP or HTTPS - Azure Logic Apps | Microsoft Docs
Vertifi - Digital Certificates
LogicApp: Certificate Authentication for HTTP GET Action not working · Issue #51400 · MicrosoftDocs/azure-docs (github.com)

How to connect with client side certificates using https module on Node.js

In production my website uses a Let's Encrypt certificate, so that the user can see in the browser the valid certificate lock.
If the user navigates to route example.com/dashboard, I would like the login using client side certificate (and not username/password).
I have generated on a server using openssl private & public key. The public key stays on server and the private key is sent to the client.
Using this tutorial, I have created in server.js
const express = require('express')
const https = require('https')
const fs = require('fs')
const masterapp = express()
var options = {
key: fs.readFileSync('/etc/ssl/certs/sslforfree/private.key'),
cert: fs.readFileSync('/etc/ssl/certs/sslforfree/certificate.crt'),
requestCert: true,
rejectUnauthorized: false,
}
And then in the middleware
const cert = req.connection.getPeerCertificate()
if (req.client.authorized) {
if (cert.subject.CN === "Client123" && cert.fingerprint256 === "AA:BB:CC:DD:00..
On Mac OS it shows correctly the prompt in the browser where I select the key (key is stored in Keychain).
Problems:
req.client.authorized is always false
How can I securely check with Node.js that the private key corresponds to public key?
Is it safer to have dashboard.example.com subdomain or route example.com/dashboard (express router)?
According to the medium article you referenced, you need to supply a ca property in the options object. This should be a list of client CAs that you trust:
Finally, we supply a list of CA certificates that we consider valid. For now, we sign client certificates with our own server key, so it will be the same as our server certificate.
, ca: [ fs.readFileSync('server_cert.pem') ]
}
You should use the CA to sign the public key of the client's generated key. To do this, you'll have to generate a CSR with the private key, then sign the CSR with the CA you have in the list. Once you do this, you can send the private key and the resulting certificate to the client in a bundle, and they will be able to authenticate against your system.
This is because you left off the ca property.
This happens between the browser and your server automatically, once you have a trusted ca.
To create a CA, you can use openssl to generate a self-signed certificate and private key.
This depends, and is out of scope for stackoverflow. You might consider asking on serverfault.com or security.stackexchange.com.

How to generate certificate request and private key files (.pem extension) from certificate file (.crt extension)

I have a .crt file. Opening up that file, I see that it starts with
-----BEGIN CERTIFICATE-----
From this file, how do I generate these 2 files?:
Certificate request file that starts with -----BEGIN CERTIFICATE REQUEST-----
Key file that starts with -----BEGIN PRIVATE KEY-----
You can not.
You have the process backwards.
The order is:
Generate a key, that is in fact a public and private part. So that would create the "PRIVATE KEY" file
Generate a CSR, that is a certificate signing request. This is computed based on the private key, without including it. But it includes your public key and other metadata
Give this CSR to a Certificate Authority, that will in turn give you back a certificate, that is something that includes your public key but that is also signed by the CA private key.
After which the CSR could be discarded.
If anyone could derive the private key from the certificate (which is basically the public key) then X.509 certificates would create no security by authentication as anyone would be able to impersonate any host/user/application.

NodeJS: HTTPS Server error w/ host key (wrong tag?)

I am receiving an error when the https server starts, something along the lines of:
Error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
I may be completely going about this the wrong way. I need to get an SSL cert from a 3rd party CA. This CA requires that I give them a Certificate Signing Request (CSR) that I have generated.
I generated a CSR using certreq.exe on Windows and provided the CSR to them. They provided the public key cert in response.
Here's where I'm a little confused. The https server has a key and cert property. As I understand, cert is for the public key (from the CA) and key is for the private key. Where's this private key??
After some googling, it appears that certreq.exe will create a key pair in the windows cert store when the CSR is generated. I exported the PFX, used openssl to extract the private key, and decrypted the key so that it was in a format that had "--BEGIN RSA PRIVATE KEY.. etc". The key looks fine to me. It's formatted the same way my previous self-signed certs were formatted which worked fine.
I used this private key for the https key property and received that asn1 wrong tag error. Am I going about getting the private key the wrong way? Or is the error something else?

Load certificate and private key for SSL in Node.js

Sorry but I have no experience with certificates and SSL, especially in Node.js. I need to configure options for express:
var https = require('https');
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('csr.pem')
};
https.createServer(options, my_app).listen(3000);
and if I try with self generated certificates (by openssl) all works like a charm.
Now, I need to change the self generated certificates with the true certificates for my domain. In Plesk I have 3 certificates: a CSR, a Private key (.key) and a Certificate (.crt) in text format, and this certificates are already working on the Plesk configuration of my server, so they are ok.
So, what I need to do now? Which of these is the key.pem and which is the csr.pem?
Sorry but I don't know, can anyone explain me?
It should be this:
key: fs.readFileSync('FILENAME.key'),
cert: fs.readFileSync('FILENAME.crt')
CSR is the request you send to the trusted third party to get a signed certificate. You will receive a certificate back from the trusted third party, and that's what you use with the private key in NodeJS.

Resources