Monday, November 1, 2021

[SOLVED] Node.js https server for localhost

Issue

I've followed this article: https://flaviocopes.com/express-https-self-signed-certificate/ for creating self-signed certificate for localhost testing my node.js app.

But it doesn't work:

node.js `v16.3.0`
openssl `(1.1.1f-1ubuntu2.3)` - `windows linux subsystem`

When I type in browser https://localhost:3000 it gives me error:

localhost uses an unsupported protocol. ERR_SSL_VERSION_OR_CIPHER_MISMATCH

When I do test curl -v https://localhost:3000 it gives me this:

*   Trying 127.0.0.1:17001...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 17001 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS alert, handshake failure (552):
* error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
* Closing connection 0
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

My code:

const https = require('https')
const app = express()

app.get('/', (req, res) => {
  res.send('Hello HTTPS!')
})

https.createServer({
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.cert')
}, app).listen(17001, () => {
  console.log('Listening...')
})

Solution

That (and others also) article contains bug that happen I guess only for latest version of node.js.

You need add encoding options while reading files {encoding: "utf8"} as below:

https.createServer({
  key: fs.readFileSync('server.key', {encoding: "utf8"}),
  cert: fs.readFileSync('server.cert', {encoding: "utf8"})
}, app).listen(17001, () => {
  console.log('Listening...')
})


Answered By - ElSajko