I want to create a Self Signed certificate for a nodejs server. I run it from macOS. I want to be able to visit pages rendered by that server over https from another device (Android) on the same wifi network through "https://192.9.200.77:8005" on Chrome. 192.9.200.77 being the IP of the server.
I managed to create a key and a certificate with OpenSSL with SAN. I installed the certificate on the Android device and on macOS.
On MacOS, the certificate is working on Safari, but not in Chrome 71.
On Android the certificate is not working either.
app.js (node server) :
const fs = require('fs');
const https = require('https');
const credentials = {
key: fs.readFileSync('keys/priv_and_pub.pem'),
cert: fs.readFileSync('keys/CA.crt')
};
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => res.send('Hello World!'));
const httpsServer = https.createServer(credentials, app);
httpsServer.listen(8005, () => console.log(`Example app listening on port 8005 in https!`));
To create the certificate, I use a configuration file :
ssl.conf
[ req ]
x509_extensions = x509_ext
distinguished_name = subject
[ subject ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = California
localityName = Locality Name (eg, city)
localityName_default = SF
organizationName = Organization Name (eg, company)
organizationName_default = my company
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = 192.9.200.77
emailAddress = Email Address
emailAddress_default = [email protected]
[ x509_ext ]
basicConstraints = CA:TRUE
subjectAltName = @alternate_names
[ alternate_names ]
DNS.1 = 192.9.200.77
And Openssl with these commands:
openssl genrsa -out priv_and_pub.key 2048
openssl req -config ssl.conf -new -x509 -sha256 -key priv_and_pub.key -subj "/C=US/ST=California/L=BSF/O=myCompany/OU=Prod/CN=192.9.200.77" -out CA.crt
Then I convert the certificate to the DER format for the Android device as recommended here:
openssl x509 -inform PEM -outform DER -in CA.crt -out CA.der.crt
And converted the priv_and_pub.key to a .pem for the node server :
cp priv_and_pub.key priv_and_pub.pem
The app.js
is working fine. I installed the .cert
in macOS and everything's fine on Safari (green lock and all), but doesn't work on Chrome : (net::ERR_CERT_COMMON_NAME_INVALID).
In the browser console, in the Security tab, I get green signs for Connection (Connection - secure (strong TLS 1.2)) and Resources (Resources - all served securely), but red flag for Certificate (Certificate - missing) and this error :
'Can not verify on the server that this is the domain 192.9.200.77, because its security certificate comes from the domain 192.9.200.77. This may be due to a misconfiguration or a connection by your hacker.' (Google Traduction from French)
Any help appreciated, spent the day on the problem ! Thks !
To clean up and reduce this solution to its core elements, the following is required to create an IP certificate that will be trusted by Chrome.
The ssl.conf file...
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[ req_distinguished_name ]
commonName = 192.168.1.10
[ req_ext ]
subjectAltName = IP:192.168.1.10
Where, of course 192.168.1.10 is the local network IP we want Chrome to trust.
Thus, the CA:True basic constraint is not required.
Create the certificate:
openssl genrsa -out key1.pem
openssl req -new -key key1.pem -out csr1.pem -config ssl.conf
openssl x509 -req -days 9999 -in csr1.pem -signkey key1.pem -out cert1.pem -extensions req_ext -extfile ssl.conf
rm csr1.pem
On Windows import the certificate into the Trusted Root Certificate Store on all client machines. On Android Phone or Tablet download the certificate to install it. Now Chrome will trust the certificate on windows and Android.
On windows dev box the best place to get openssl.exe is from "c:\Program Files\Git\usr\bin\openssl.exe"
I resolved my problem by changing the subjectAltName
in the ssl.conf
file, by adding IP:
in front of the IP adress :
ssl.conf
file :
[ x509_ext ]
basicConstraints = CA:TRUE
subjectAltName = IP:192.9.200.77
and I also removed the [ alternate_names ]
section.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With