Trust self-signed certificate | express - node.js

When trying to login to my page on firefox (no error on chromium based browsers) I get the error
ERROR_SELF_SIGNED_CERT
at the options-request.
I tried adding process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; to the backend and also added rejectedUnauthorized
https.createServer({
key: fs.readFileSync('certs/key.pem', 'utf8'),
cert: fs.readFileSync('certs/cert.pem', 'utf8'),
rejectUnauthorized: false
}, app)

This is an expected behavior, Firefox doesn't recognize the root authority of your self-signed certificated. To avoid this warning from Firefox, you can add the generated root certificated to the list of trusted root certificate.

Related

ERR_SSL_VERSION_OR_CIPHER_MISMATCH in node js

I recently purchased a personal ssl certificate from Positive ssl. After i got everything sorted out with activating it and the validation, I was finally able to download the certificate files.
The files i got were:
www.niknet.ddns.net.ca-bundle
www.niknet.ddns.net.crt
www.niknet.ddns.net.p7b
Before I only used .key and .crt
and it worked great but now i am using the .ca-bundle and the .crt file
this is the code i use to include those files into the ssl library in node js
var httpPort = process.env.PORT || 80;
var httpsPort = process.env.PORT || 443;
var server = http.createServer(app).listen(httpPort);
var server = https.createServer({
secureProtocol : 'TLSv1_2_server_method',
ciphers : "AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH",
honorCipherOrder : true,
ca: fs.readFileSync(__dirname + '/niknet_ddns_net.ca-bundle'),
cert: fs.readFileSync(__dirname + '/niknet_ddns_net.crt')
},app).listen(httpsPort);
var io = require('socket.io').listen(server);
but I can't for the life of me get the certificate to work properly.
I just get this error
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
I've been reading other posts and have tried adding their code but nothing works.
I also read somewhere that the ssl or tls library for node.js is outdated and that my certificate could be too new. If that's true, are there any other third-party ssl libraries I could use?
run this command:
openssl req -nodes -new -x509 -keyout server.key -out server.cert
Just remember to set this to localhost:
Common Name (e.g. server FQDN or YOUR name) []: localhost
then
https.createServer({
key: fs.readFileSync('./ssl/server.key'),
cert: fs.readFileSync('./ssl/server.cert')
},app)
ERR_SSL_VERSION_OR_CIPHER_MISMATCH will appear if the added certificate are not indicated properly in the first argument of createServer().
tested key and crt with openssl using bellow command (try in browser https://hostname:8888).. and found the exact cipher missing.
openssl s_server -cert server.crt -key server.key -CAfile octopz.zende.sk.ca-bundle -accept 8888 -www
Then added to the nodejs code.
var server = https.createServer({
key: privateKey,
cert: certificate,
ca: certificateAuthority,
ciphers: [
"ECDHE-RSA-AES128-SHA256",
"DHE-RSA-AES128-SHA256",
"AES128-GCM-SHA256",
"RC4",
"HIGH",
"!MD5",
"!aNULL"
].join(':'),
}, app);
it worked!!
We have lots of dupes of this for other languages, but the closest I can find for nodejs is How to create an HTTPS server in Node.js? which is not specific or ERR_SSL_VERSION_OR_CIPHER_MISMATCH with node v7.9.0 https which is not answered. So:
SSL/TLS server including an HTTPS server needs a privatekey AND certificate/chain (with rare exceptions not applicable here). You can use a CA-issued cert (and chain) instead of a self-created (and usually self-signed) cert, as long as the CA-issued cert is for the same privatekey, but you must still provide the privatekey. You can use cert and key together, or you can combine the cert (and optionally chain) and key into a PKCS12-also-called-PFX file, and use pfx.
In addition to the Q you asked, and arguably offtopic for SO, don't use RC4. It's considered broken cryptographically, though still on average moderately difficult/costly in practice, and most standards for using SSL/TLS/HTTPS prohibit it for several years now, particularly rfc7465.

How to enable SSL connection a NodeJS (Express) based Server

Following is the script I found on NodeJS Official Website:
// curl -k https://localhost:8000/
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
I'm completely new to SSL thing. I read some tutorials on how to enable SSL on Nodejs but still quite not confident with the process.
I have a domain name (Godaddy), SSL (Namecheap) and Cloud Server (Digital Ocean with an application deployed on HTTP prefix).
Whenever I open my Login page of my website, Google Chrome mark it as "Not secure" so I wanted to add SSL to the website.
What things I need to do on the NodeJS server (Express) and what things I need to do on Namecheap? What will be the sequence of doing that? What are cmd lines to generate .pem .csr files?
I'm didn't found and comprehensive guide laying down all the steps in a concise manner so just laid down the steps concisely (if possible) with the links to the resources for further digging.
And also, how can I use express framework to create https server in liue of above script?
That script is correct for setting the certs for your https. If your site is public, as it seems, then you'll want to buy certs from your ssl service, Namecheap in your example. Then you would move them to your host and reference them in the options object in your example. However, you can generate your own ssl certs and that will work as well. Though, any users will be warned that they're not trusted since you self signed/created them. I suggest going with the Namecheap option.
Note: You only have an https server in your example and anyone attempting to access your site via http will receive a blank page. You'll need to also create an http server, via the following:
var http = require('http');
http.createServer(...);
I would suggest having the http server simply redirect to the https url.
My code and error is here:
no such directory found error:
key: fs.readFileSync('../private.key'),
cert: fs.readFileSync('../public.cert')
error, no such directory found
key: fs.readFileSync('./private.key'),
cert: fs.readFileSync('./public.cert')
Working code should be
key: fs.readFileSync(__dirname + '/private.key', 'utf8'),
cert: fs.readFileSync(__dirname + '/public.cert', 'utf8')
Complete https code is:
const https = require('https');
const fs = require('fs');
// readFileSync function must use __dirname get current directory
// require use ./ refer to current directory.
const options = {
key: fs.readFileSync(__dirname + '/private.key', 'utf8'),
cert: fs.readFileSync(__dirname + '/public.cert', 'utf8')
};
// Create HTTPs server.
var server = https.createServer(options, app);
This is my working code for express 4.0.
express 4.0 is very different from 3.0 and others.
4.0 you have /bin/www file, which you are going to add https here.
"npm start" is standard way you start express 4.0 server.
readFileSync() function should use __dirname get current directory
while require() use ./ refer to current directory.
First you put private.key and public.cert file under /bin folder,
It is same folder as WWW file.

https error in nodejs?

I have installed SSL certificated on ubutunu.
this is not self generated certificates.
I have implemented code
var sslOptions = {
key: fs.readFileSync('/etc/ssl/private/private.key'),
cert: fs.readFileSync('/etc/ssl/certs/STAR_certs.crt'),
//ca: fs.readFileSync('/etc/ssl/certs/AddTrustExternalCARoot.crt'),
requestCert: true,
rejectUnauthorized: false
};
and i do confirm all above files are present. and STAR_certs.crt is having root permissions.
And i got following error now
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
at Object.exports.createCredentials (crypto.js:100:17)
at Server (tls.js:1130:28)
at new Server (https.js:35:14)
at Object.exports.createServer (https.js:54:10)
Any idea. I dnt have any pem file
Thanks
You need to check that your private.key and STAR_certs.crt files are in format, supported by OpenSSL (which is PEM). If they are not, you need to convert those files. You will find conversion instructions in other StackOverflow questions and answers ( I don't know in which format your files are now, so I can't direct you to any particular answer).

Node.js server + SSL = ERR_CONNECTION_CLOSED

I've got an node.js app which was running perfectly on http.
Then I added self-signed cert to buildup and test ssl connection.
When it worked out (with chrome notify that somebody could steal something) I bought the ssl cert from local certifier.
When I put the new cert server starts up normally but the browser says:
Error code: ERR_CONNECTION_CLOSED
Now what could be the reason?
https = require('https'),
fs = require('fs');
var keys_dir = "./ssl/"
var sslOptions = {
key : fs.readFileSync(keys_dir + 'server.key'),
cert : fs.readFileSync(keys_dir + 'certificate.crt'),
ca: [fs.readFileSync(keys_dir + 'nazwa1.crt'), fs.readFileSync(keys_dir +'nazwa2.crt')]
};
https.createServer(sslOptions, app).listen(app.get('port'), function(){ *** });
the port is 443.
Key is RSA PRIVATE KEY. Cert is based on it.
Node -v v0.10.25
Well I fixed it:
I did check md5 of key and cert and they were different. So i recreated cert and all went nice and smooth.

Install root certificate to Node.js (HTTPS Client)

I would like to connect to an internal corporate server with Node.js as a client via HTTPS.
How do I install my internal root certificate to Node.js, so the certificate validation is successful?
I don't want to disable certificate validation.
I solved the problem.
Use this, it works as charm: https://github.com/coolaj86/node-ssl-root-cas
Create a certificates folder
Place your root certificate there
Load the certificate with the module metnioned above
If you use Sails.js, put the code to config/bootstrap.js
Add an environment variable:
NODE_EXTRA_CA_CERTS=file
When set, the well known "root" CAs (like VeriSign) will be extended with the extra certificates in file. The file should consist of one or more trusted certificates in PEM format. A message will be emitted (once) with process.emitWarning() if the file is missing or malformed, but any errors are otherwise ignored.
Note that neither the well known nor extra certificates are used when the ca options property is explicitly specified for a TLS or HTTPS client or server.
This environment variable is ignored when node runs as setuid root or has Linux file capabilities set.
Hope this help someone:
var https = require('https');
var fs = require('fs');
var https_options = {
key: fs.readFileSync("/path/to/private.key"),
cert: fs.readFileSync("/path/to/your_domain_name.crt"),
ca: [
fs.readFileSync('path/to/CA_root.crt'),
fs.readFileSync('path/to/ca_bundle_certificate.crt')
]
};
Ref: https://cheapsslsecurity.com/blog/how-to-install-ssl-certificate-on-node-js/
And you can use this link to check your cert:
https://www.digicert.com/help/

Resources