Creating Secure WebSocket with Node.js throws error [duplicate] - node.js

I am messing with login form right now with node.js, I tried creating a pem key and csr using
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem
However I been getting errors for running node server.js
Here is my server.js
var http = require('http'),
express = require('express'),
UserServer = require('./lib/user-server');
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./key.pem', 'utf8'),
cert: fs.readFileSync('./csr.pem', 'utf8')
};
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
var httpserver = http.createServer(app).listen('3004', '127.0.0.1');
var https_server = https.createServer(options, app).listen('3005', '127.0.0.1');
UserServer.listen(https_server);
Here is the error
crypto.js:104
if (options.cert) c.context.setCert(options.cert);
^
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
at Object.exports.createCredentials (crypto.js:104:31)
at Server (tls.js:1107:28)
at new Server (https.js:35:14)
at Object.exports.createServer (https.js:54:10)
I tried running
openssl x509 -text -inform DER -in key.pem
It gives
unable to load certificate
140735208206812:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1319:
140735208206812:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:381:Type=X509
I am not exactly sure what does the error mean as my encryption file is .pem file already, so any help would be much appreciated.
Thanks

You are probably using the wrong certificate file, what you need to do is generate a self signed certificate which can be done as follows
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem
openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out server.crt
then use the server.crt
var options = {
key: fs.readFileSync('./key.pem', 'utf8'),
cert: fs.readFileSync('./server.crt', 'utf8')
};

I removed this error by write the following code
Open Terminal
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem
openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out server.crt
Now use the server.crt and key.pem file
app.js or server.js file
var https = require('https');
var https_options = {
key: fs.readFileSync('key.pem', 'utf8'),
cert: fs.readFileSync('server.crt', 'utf8')
};
var server = https.createServer(https_options, app).listen(PORT);
console.log('HTTPS Server listening on %s:%s', HOST, PORT);
It works but the certificate is not trusted. You can view the image in image file.

For me the issues was I had the key and cert swapped.
var options = {
key: fs.readFileSync('/etc/letsencrypt/live/mysite.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/mysite.com/fullchain.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/mysite.com/chain.pem')
};
EDIT
More Complete Example (Maybe not completely functional)
Server.js
var fs = require('fs');
var sessionKey = 'ai_session:';
var memcachedAuth = require('memcached-auth');
var clients = {};
var users = {};
var options = {
key: fs.readFileSync('/etc/letsencrypt/live/somesite.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/somesite.com/fullchain.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/somesite.com/chain.pem')
};
var origins = 'https://www.somesite.com:*';
var https = require('https').createServer(options,function(req,res){
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', origins);
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', '*');
});
var io = require('socket.io')(https);
https.listen(3000);
io.sockets.on('connection', function(socket){
socket.on('auth', function(data){
var session_id = sessionKey+data.token;
memcachedAuth.is_logged_in(session_id).then( (response) => {
if(response.is_logged_in){
// user is logged in
socket.emit('is_logged_in', true);
messenger.addUser(socket);
// dynamic room
socket.on('room', function(room){
socket.join(room);
console.log('joing room '+room);
});
socket.on('message', function(data){
messenger.receive(data.message_data);
});
}else{
// Not logged in
socket.emit('is_logged_in', false);
}
}).catch( (error) => {
console.log(error);
});
});
});
var messenger = {
socket: (socket)=>{
return socket;
},
subscribe: (room)=>{
},
unsubscribe: (room)=>{
},
send: (data)=>{
},
receive: (data)=>{
console.log(data);
//connected
if (clients[data.user_name]){
console.log('user');
}
},
addUser: (socket)=>{
socket.on('add-user', function(data){
clients[data] = {
"socket": socket.id
};
console.log('Adding User:' + data);
console.log(clients);
});
},
private: (socket)=>{
// Not working yet...
socket.on('message', function(data){
console.log("Sending: " + data + " to " + data.user_name);
if (clients[data.user_name]){
io.sockets.connected[clients[data.user_name].socket].emit("response", data);
} else {
console.log("User does not exist: " + data.user_name);
}
});
},
disconnect:()=>{
//Removing the socket on disconnect
socket.on('disconnect', function() {
for(var name in clients) {
if(clients[name].socket === socket.id) {
delete clients[name];
break;
}
}
});
}
}
I have created a repo on github including a more complete version of the above code if anyone is interested: https://github.com/snowballrandom/Memcached-Auth

Was facing the same problem In my case I changed the option parameter of cert to pfx & removed utf8 encoding.
before:
var options = {
hostname : 'localhost',
path : '/',
method : 'POST',
cert: fs.readFileSync(testCert, 'utf8'),
passphrase:passphrase,
agent:false,
rejectUnauthorized:false
};
after:
var options = {
hostname : 'localhost',
path : '/',
method : 'POST',
pfx: fs.readFileSync(testCert),
passphrase:passphrase,
agent:false,
rejectUnauthorized:false
};

I actually just had this same error message.
The problem was I had key and cert files swapped in the configuration object.

For me, after trying all above solutions it ended up being a problem related to encoding. Concisely, my key was encoded using 'UTF-8 with BOM'. It should be UTF-8 instead.
To fix it, at least using VS Code follow this steps:
Open the file and click on the encoding button at the status bar (at the bottom) and select 'Save with encoding'.
Select UTF-8.
Then try using the certificate again.
I suppose you can use other editors that support saving with the proper encoding.
Source: error:0906d06c:pem routines:pem_read_bio:no start line, when importing godaddy SSL certificate
P.D I did not need to set the encoding to utf-8 option when loading the file using the fs.readFileSync function.
Hope this helps somebody!

I faced with the problem like this.
The problem was that I added the public key without '-----BEGIN PUBLIC KEY-----' at the beginning and without '-----END PUBLIC KEY-----'.
So it causes the error.
Initially, my public key was like this:
-----BEGIN PUBLIC KEY-----
WnsbGUXbb0GbJSCwCBAhrzT0s2KMRyqqS7QBiIG7t3H2Qtmde6UoUIcTTPJgv71
......
oNLcaK2wKKyRdcROK7ZTSCSMsJpAFOY
-----END PUBLIC KEY-----
But I used just this part:
WnsbGUXb+b0GbJSCwCBAhrzT0s2KMRyqqS7QBiIG7t3H2Qtmde6UoUIcTTPJgv71
......
oNLcaK2w+KKyRdcROK7ZTSCSMsJpAFOY

If you are using windows, you should make sure that the certificate file csr.pem and key.pem don't have unix-style line endings. Openssl will generate the key files with unix style line endings. You can convert these files to dos format using a utility like unix2dos or a text editor like notepad++

I guess this is because your nodejs cert has expired. Type this line : npm set registry http://registry.npmjs.org/ and after that try again with npm install . This actually solved my problem.

For me, the solution was to replace \\n (getting formatted into the key in a weird way) in place of \n
Replace your
key: <private or public key>
with
key: (<private or public key>).replace(new RegExp("\\\\n", "\g"), "\n")

If you log the
var options = {
key: fs.readFileSync('./key.pem', 'utf8'),
cert: fs.readFileSync('./csr.pem', 'utf8')
};
You might notice there are invalid characters due to improper encoding.

Corrupted cert and/or key files
For me it was just corrupted files. I copied the contents from GitHub PullRequest webpage and I guess I added an extra space somewhere or whatever... once I grabbed the raw thing and replaced the file, it worked.

Generate the private key and server certificate with specific expiry date or with infinite(XXX) expiry time and self sign it.
$ openssl req -x509 -sha256 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
$ Enter a private key passphrase...`
Then it will work!

Related

error : "ERR_SSL_VERSION_OR_CIPHER_MISMATCH"

I want to use https on my web locally.
Using Nuxt framework, and create a nodejs server.
I follow these command to create key.
openssl genrsa 2048 > server.key
chmod 400 server.key
openssl req -new -x509 -nodes -sha256 -days 365 -key server.key -out server.crt
then have these code on my server.
const app = express()
const path = require('path')
const fs = require('fs')
const option = {
https: {
key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
}
}
const server = require('https').createServer(option, app)
server.listen(port, host)
I have hosts setting 172.0.0.1 local.xxx.com.
when I call my web on chrome https://local.xxx.com
I will get error: ERR_SSL_VERSION_OR_CIPHER_MISMATCH
try others browser, get similar error
fix it!
this error cause my option have excessive 'https',fix it then it works.
const option = {
key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
}

node.js localhost https server not working anything

const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
https.createServer(options,(req,res)=>{
console.log('https server start');
}).listen(8080,'localhost');
Dear every one,
I tried make https server... and this code.
But not working.
Before i make key.pem, cert.pem for localhost server
Like this code
openssl genrsa 1024 > key.pem
openssl req -x509 -new -key key.pem > cert.pem
and this thing in the same folder
but not working like this enter image description here
Thank you and Regards.!
Your "it's not working" image isn't showing any errors, so it seems to start up just fine.
However, the code that handles the request isn't actually sending back a response, which would result in requests just "hanging".
Instead, try this:
https.createServer(options, (req, res) => {
res.end('Hello, world!');
}).listen(8080, 'localhost', () => {
console.log('https server start');
});

How to create a .pem and .cert files for node js project

I want to run an https server. I found this code online :
var fs = require('fs'),
http = require('http'),
https = require('https'),
express = require('express');
var port = 8000;
var options = {
key: fs.readFileSync('./ssl/privatekey.pem'),
cert: fs.readFileSync('./ssl/certificate.pem'),
};
var app = express();
var server = https.createServer(options, app).listen(port, function(){
console.log("Express server listening on port " + port);
});
app.get('/', function (req, res) {
res.writeHead(200);
res.end("hello world\n");
});
the problem is that i do not know how to create those files.
is there a way of generating them using the node shell? (working on Windows)
Take a look at this: How to create .pem files for https web server
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
If you have openSSL installed you should be able to type this command directly into the command prompt on windows or terminal on mac.
import crypto from 'crypto'
import { writeFileSync } from 'fs';
const certKey = crypto.randomBytes(1024).toString('hex')
const certKeyFormatted = certKey.match(/.{1,64}/g).join("\n")
const certContents =
'-----BEGIN CERTIFICATE-----' + "\n" +
certKeyFormatted + "\n" +
'-----END CERTIFICATE-----'
console.log('generated certificate')
console.log()
console.log(certContents)
const filePath = 'signingKey.pem'
writeFileSync(
filePath,
certContents,
{ encoding: 'utf8' }
);
console.log()
console.log('certificate saved to', filePath)
this gives something like
-----BEGIN CERTIFICATE-----
018bd0f56deb8f3695e9bcc73b8031829b4505a6b49257e41a5597743135473a
34ca92304cbb293ea05d3a5e8fff497d32e398196f8c94def68a3333bec3343e
3248a97e3af7d1ae69e8993c9a2d0d0770ddc0694267a63be241c18204363074
84542b3205a06a05d05607944492c914f04f630a93efdb1d5fec796071951a7c
...
67ea551c13af07d6f3fcefdd6d2f17e4aa084b9c82254a52d2903791e31418cf
5d9f07137c5188fa26ac480b9c7c25ca6dd7c1464a3bcc53294d84770ad995a4
efa357956865134e97ec02a172111d4a0db68f63cb3f68d1438fe03bef55f937
ee5d60af45a53f8cd43e8ce6ea26d75ff09714468914274443e581acf1c96bb5
-----END CERTIFICATE-----

Node.js https pem error: routines:PEM_read_bio:no start line

I am messing with login form right now with node.js, I tried creating a pem key and csr using
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem
However I been getting errors for running node server.js
Here is my server.js
var http = require('http'),
express = require('express'),
UserServer = require('./lib/user-server');
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./key.pem', 'utf8'),
cert: fs.readFileSync('./csr.pem', 'utf8')
};
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
var httpserver = http.createServer(app).listen('3004', '127.0.0.1');
var https_server = https.createServer(options, app).listen('3005', '127.0.0.1');
UserServer.listen(https_server);
Here is the error
crypto.js:104
if (options.cert) c.context.setCert(options.cert);
^
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
at Object.exports.createCredentials (crypto.js:104:31)
at Server (tls.js:1107:28)
at new Server (https.js:35:14)
at Object.exports.createServer (https.js:54:10)
I tried running
openssl x509 -text -inform DER -in key.pem
It gives
unable to load certificate
140735208206812:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1319:
140735208206812:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:381:Type=X509
I am not exactly sure what does the error mean as my encryption file is .pem file already, so any help would be much appreciated.
Thanks
You are probably using the wrong certificate file, what you need to do is generate a self signed certificate which can be done as follows
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem
openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out server.crt
then use the server.crt
var options = {
key: fs.readFileSync('./key.pem', 'utf8'),
cert: fs.readFileSync('./server.crt', 'utf8')
};
I removed this error by write the following code
Open Terminal
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem
openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out server.crt
Now use the server.crt and key.pem file
app.js or server.js file
var https = require('https');
var https_options = {
key: fs.readFileSync('key.pem', 'utf8'),
cert: fs.readFileSync('server.crt', 'utf8')
};
var server = https.createServer(https_options, app).listen(PORT);
console.log('HTTPS Server listening on %s:%s', HOST, PORT);
It works but the certificate is not trusted. You can view the image in image file.
For me the issues was I had the key and cert swapped.
var options = {
key: fs.readFileSync('/etc/letsencrypt/live/mysite.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/mysite.com/fullchain.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/mysite.com/chain.pem')
};
EDIT
More Complete Example (Maybe not completely functional)
Server.js
var fs = require('fs');
var sessionKey = 'ai_session:';
var memcachedAuth = require('memcached-auth');
var clients = {};
var users = {};
var options = {
key: fs.readFileSync('/etc/letsencrypt/live/somesite.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/somesite.com/fullchain.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/somesite.com/chain.pem')
};
var origins = 'https://www.somesite.com:*';
var https = require('https').createServer(options,function(req,res){
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', origins);
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', '*');
});
var io = require('socket.io')(https);
https.listen(3000);
io.sockets.on('connection', function(socket){
socket.on('auth', function(data){
var session_id = sessionKey+data.token;
memcachedAuth.is_logged_in(session_id).then( (response) => {
if(response.is_logged_in){
// user is logged in
socket.emit('is_logged_in', true);
messenger.addUser(socket);
// dynamic room
socket.on('room', function(room){
socket.join(room);
console.log('joing room '+room);
});
socket.on('message', function(data){
messenger.receive(data.message_data);
});
}else{
// Not logged in
socket.emit('is_logged_in', false);
}
}).catch( (error) => {
console.log(error);
});
});
});
var messenger = {
socket: (socket)=>{
return socket;
},
subscribe: (room)=>{
},
unsubscribe: (room)=>{
},
send: (data)=>{
},
receive: (data)=>{
console.log(data);
//connected
if (clients[data.user_name]){
console.log('user');
}
},
addUser: (socket)=>{
socket.on('add-user', function(data){
clients[data] = {
"socket": socket.id
};
console.log('Adding User:' + data);
console.log(clients);
});
},
private: (socket)=>{
// Not working yet...
socket.on('message', function(data){
console.log("Sending: " + data + " to " + data.user_name);
if (clients[data.user_name]){
io.sockets.connected[clients[data.user_name].socket].emit("response", data);
} else {
console.log("User does not exist: " + data.user_name);
}
});
},
disconnect:()=>{
//Removing the socket on disconnect
socket.on('disconnect', function() {
for(var name in clients) {
if(clients[name].socket === socket.id) {
delete clients[name];
break;
}
}
});
}
}
I have created a repo on github including a more complete version of the above code if anyone is interested: https://github.com/snowballrandom/Memcached-Auth
Was facing the same problem In my case I changed the option parameter of cert to pfx & removed utf8 encoding.
before:
var options = {
hostname : 'localhost',
path : '/',
method : 'POST',
cert: fs.readFileSync(testCert, 'utf8'),
passphrase:passphrase,
agent:false,
rejectUnauthorized:false
};
after:
var options = {
hostname : 'localhost',
path : '/',
method : 'POST',
pfx: fs.readFileSync(testCert),
passphrase:passphrase,
agent:false,
rejectUnauthorized:false
};
I actually just had this same error message.
The problem was I had key and cert files swapped in the configuration object.
For me, after trying all above solutions it ended up being a problem related to encoding. Concisely, my key was encoded using 'UTF-8 with BOM'. It should be UTF-8 instead.
To fix it, at least using VS Code follow this steps:
Open the file and click on the encoding button at the status bar (at the bottom) and select 'Save with encoding'.
Select UTF-8.
Then try using the certificate again.
I suppose you can use other editors that support saving with the proper encoding.
Source: error:0906d06c:pem routines:pem_read_bio:no start line, when importing godaddy SSL certificate
P.D I did not need to set the encoding to utf-8 option when loading the file using the fs.readFileSync function.
Hope this helps somebody!
I faced with the problem like this.
The problem was that I added the public key without '-----BEGIN PUBLIC KEY-----' at the beginning and without '-----END PUBLIC KEY-----'.
So it causes the error.
Initially, my public key was like this:
-----BEGIN PUBLIC KEY-----
WnsbGUXbb0GbJSCwCBAhrzT0s2KMRyqqS7QBiIG7t3H2Qtmde6UoUIcTTPJgv71
......
oNLcaK2wKKyRdcROK7ZTSCSMsJpAFOY
-----END PUBLIC KEY-----
But I used just this part:
WnsbGUXb+b0GbJSCwCBAhrzT0s2KMRyqqS7QBiIG7t3H2Qtmde6UoUIcTTPJgv71
......
oNLcaK2w+KKyRdcROK7ZTSCSMsJpAFOY
If you are using windows, you should make sure that the certificate file csr.pem and key.pem don't have unix-style line endings. Openssl will generate the key files with unix style line endings. You can convert these files to dos format using a utility like unix2dos or a text editor like notepad++
I guess this is because your nodejs cert has expired. Type this line : npm set registry http://registry.npmjs.org/ and after that try again with npm install . This actually solved my problem.
For me, the solution was to replace \\n (getting formatted into the key in a weird way) in place of \n
Replace your
key: <private or public key>
with
key: (<private or public key>).replace(new RegExp("\\\\n", "\g"), "\n")
If you log the
var options = {
key: fs.readFileSync('./key.pem', 'utf8'),
cert: fs.readFileSync('./csr.pem', 'utf8')
};
You might notice there are invalid characters due to improper encoding.
Corrupted cert and/or key files
For me it was just corrupted files. I copied the contents from GitHub PullRequest webpage and I guess I added an extra space somewhere or whatever... once I grabbed the raw thing and replaced the file, it worked.
Generate the private key and server certificate with specific expiry date or with infinite(XXX) expiry time and self sign it.
$ openssl req -x509 -sha256 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
$ Enter a private key passphrase...`
Then it will work!

How can you get yourself a key and certificate pair for using in https?

I am trying to use the https module in Node.js.
Here's the code:
var options = {
key : <key comes here>,
cert : <key comes here>
};
https.createServer(options, app).listen(app.get('port'));
You can use OpenSSL,
A private key is created like this
openssl genrsa -out ryans-key.pem 1024
The first step to getting a certificate is to create a "Certificate Signing Request" (CSR) file. This is done with:
openssl req -new -key ryans-key.pem -out ryans-csr.pem
To create a self-signed certificate with the CSR, do this:
openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem
To create .pfx or .p12, do this:
openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \
-certfile ca-cert.pem -out agent5.pfx
Here is a simple example echo server
var tls = require('tls');
var fs = require('fs');
var options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem'),
// This is necessary only if using the client certificate authentication.
requestCert: true,
// This is necessary only if the client uses the self-signed certificate.
ca: [ fs.readFileSync('client-cert.pem') ]
};
var server = tls.createServer(options, function(cleartextStream) {
console.log('server connected',
cleartextStream.authorized ? 'authorized' : 'unauthorized');
cleartextStream.write("welcome!\n");
cleartextStream.setEncoding('utf8');
cleartextStream.pipe(cleartextStream);
});
server.listen(8000, function() {
console.log('server bound');
});
you can refer to http://nodejs.org/api/tls.html for more info,
Regards
Follow the openssl instructions found at the Node.js website.

Resources