HTTPS in Nodejs - error:06065064 digital envelope routines evp_decryptfinal_ex bad decrypt

Viewed 12365

We tried to install our Hapis (Nodejs Version 14) Web service on our customer's server. It ran under HTTP for months, but when we went to enable HTTPS with the appropriate paths to the cert and key it fails when the service starts up with:

error:06065064:digital envelope routines:EVP_Decryptfinal_ex:bad decrypt

Their certificate and key are generated using the Venafi online portal. It gave them a crt and key. The crt uses a Signature algorithm: sha256RSA, Signature hash algorithm of sha256, and Thumbprint algorith: sha1.

Also, the private key is a RSA PRIVATE KEY with Proc-Type: 4,ENCRYPTED and DEK-Info: DES-EDE3-CBC.

I am not sure what is going on, because HTTPS works fine on our development servers.

  1. Is the problem in HapiJS?
  2. Is the problem with the certificate or key themselves?
  3. Is there an Node option I need to be passing in when creating the service?

Please help.

3 Answers

The specified error 06065064:digital envelope routines:EVP_Decryptfinal_ex:bad decrypt occurs in an SSL/TLS connection using OpenSSL (which is what nodejs modules like tls and https actually use) when the privatekey is encrypted (with a passphrase) and the correct passphrase is not provided to decrypt it. The described file format, beginning with a line -----BEGIN RSA PRIVATE KEY----- followed by lines Proc-Type: and DEK-Info: is indeed one of the encrypted formats used by OpenSSL. Specifically this is the encrypted 'traditional' or 'legacy' format; the PKSC8 format added about 2000 but still considered new(!) uses -----BEGIN ENCRYPTED PRIVATE KEY----- and no 822-style headers, only base64 (of the encrypted structure defined by PKCS8); see ursinely-verbose https://security.stackexchange.com/questions/39279/stronger-encryption-for-ssh-keys/#52564 about OpenSSH's use of OpenSSL, which is basically the same as nodejs's use.

The tls module and others that build on it including https ultimately read the key(s) and cert(s) using tls.createSecureContext which accepts in options a member passphrase, or if you need to use multiple keys (and certs) you can provide a passphrase for each key as described in the linked doc.

Alternatively you can avoid the need for a passphrase by converting the key to an unencrypted file, if acceptable under applicable security policies and regulations. (Good policies may prohibit this, but they usually also prohibit getting the privatekey from or providing it to any other system, especially one 'online' somewhere, and your customer is doing the latter.) To retain traditional format do

openssl rsa -in oldfile -out newfile 
# and give the passphrase when prompted, or see the man page about -passin

or you can use the 'new' PKCS8 format with

openssl pkey -in oldfile -out newfile
# technically only in release 1.0.0 up, but pretty much everyone is there now
#
# or in all versions back to about 2000
openssl pkcs8 -topk8 -nocrypt -in oldfile -out newfile

For me this error occured after pulling some old code that was workign to a fresh system, I was using too current of a node Version, I downgraded from 17 to 16 and that solved my problem.

Tried checking the github issues related to the TLS, handshake and versions. But couldn't find any. The final fix was the one suggested by @Greggory Wiley.

Installed nvm - downgraded the node and npm versions. Recomplied the code. And it worked.

Related