使用Node.js的HTTPS——错误:06065064数字信封程序EVP_DecryptFinal_ex解密失败。

6
我们尝试在客户的服务器上安装我们的Hapis (Nodejs版本14) Web服务。它在HTTP下运行了数月,但当我们尝试使用适当的路径启用HTTPS时,服务在启动时失败,并显示以下错误信息:error:06065064:digital envelope routines:EVP_Decryptfinal_ex:bad decrypt。他们的证书和密钥是使用Venafi在线门户生成的。它给出了一个crt和key。crt使用签名算法:sha256RSA,签名哈希算法为sha256,Thumbprint算法为sha1。此外,私钥是带有Proc-Type: 4,ENCRYPTED和DEK-Info: DES-EDE3-CBC的RSA PRIVATE KEY。我不确定发生了什么事,因为HTTPS在我们的开发服务器上正常工作。请回答以下问题:
  1. 问题出在HapiJS吗?
  2. 证书或密钥本身有问题吗?
  3. 创建服务时是否需要传递Node option参数?
请帮忙解决。

1
通常情况下,如果不是总是由于提供错误的密码来解密(私有)密钥而导致该错误。请检查一下,并避免使用非ASCII字符。您没有明确说明这些是否为相同的文件(您可以在本地进行测试),尽管我希望不是因为您不应该能够证明拥有他们的域名或反之亦然。 (说到这一点,使用一些未知的在线来源是不好的安全实践,但这超出了您的问题范围,对于SO也是离题的。) - dave_thompson_085
谢谢您。我已经更新了问题,并提供了crt和key的详细信息。我没有指定密码,因为在我们的测试环境中从来没有必要这样做。 - Croeber
1
是的,那个密钥文件被使用口令短语(也称为密码)加密,因此您需要提供口令短语,使用tls.createSecureContext的passphrase选项(这是https底层使用的内容)。或者,如果用户和任何适用的政策或法规允许,可以使用命令行openssl将加密的密钥文件转换为非加密文件,然后您就不需要任何口令短语。 - dave_thompson_085
如果您将您的评论移动到答案面板,我会将其标记为答案。 - Croeber
强调@dave_thompson_085的答案: “通常情况下,如果不是始终如一地提供错误的解密密码,就会出现该错误。”这正是我在寻找的内容,搜索该错误消息并发现它实际上意味着“错误的解密密码”。 - R.M. Buda
5个回答

8
在使用OpenSSL(即nodejs模块tls和https实际使用的内容)的SSL/TLS连接中,当私钥受到加密(使用密码短语)并且未提供正确的密码短语进行解密时,会发生指定错误06065064:digital envelope routines:EVP_Decryptfinal_ex:bad decrypt。所描述的文件格式以-----BEGIN RSA PRIVATE KEY-----开头,后跟Proc-Type:DEK-Info:行,这确实是OpenSSL使用的加密格式之一。具体来说,这是加密的“传统”或“遗留”格式; PKSC8格式于2000年左右添加,但仍被认为是新的!使用-----BEGIN ENCRYPTED PRIVATE KEY-----而没有822样式的标头,只有base64(由PKCS8定义的加密结构);请参见关于OpenSSH使用OpenSSL的详细信息,网址为:https://security.stackexchange.com/questions/39279/stronger-encryption-for-ssh-keys/#52564,这与nodejs的使用基本相同。 tls模块和其他建立在其之上的模块包括https,最终使用tls.createSecureContext读取密钥和证书,其中options接受一个成员passphrase,或者如果需要使用多个密钥(和证书),则可以按照链接的文档为每个密钥提供密码短语。
另外,如果符合适用的安全策略和法规,则可以通过将密钥转换为未加密文件来避免需要密码短语。(良好的策略可能会禁止此操作,但通常也会禁止从任何其他系统获取私钥或向其提供私钥,特别是在线的系统,并且您的客户正在执行后者。)要保留传统格式,请执行以下操作:
openssl rsa -in oldfile -out newfile 
# and give the passphrase when prompted, or see the man page about -passin

或者您可以使用'新的' PKCS8 格式

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

3

在我将一些旧代码从一个工作中的系统拉到一个新的系统时,出现了这个错误。 我使用的 node 版本太新了,我将它从 17 降级到 16,问题就解决了。


1
我在使用yarn构建项目时遇到了错误。将Node从17降级到16后,一切都开始正常工作了。非常感谢。 - Stalinko
@Stalinko 很高兴听到这个有所帮助,最近在使用 Node 17 时也遇到了同样的错误。我喜欢通过 NVM https://github.com/nvm-sh/nvm 安装 Node,然后使用像 NVM Use 16 这样的命令非常容易切换版本。 - Greggory Wiley

2

我遇到了同样的问题,我想说接受的答案是好的,除了它没有提供一个使用口令短语的示例。

这是在我的情况下适用的代码,用于 express.js

const server = https
  .createServer(
    {
      key: fs.readFileSync("./root/ca/cakey.pem"),
      cert: fs.readFileSync("./root/ca/cacert.pem"),
      passphrase: "abcdefg",
    },
    app
  )
  .listen(PORT, () => {
    console.log(`Secure server listening on port:${PORT}`);
  });


1
尝试检查与TLS、握手和版本相关的GitHub问题,但未找到任何问题。最终修复建议来自@Greggory Wiley。安装了nvm-降级了node和npm版本。重新编译代码。然后它就可以工作了。

1
最好给原始解决方案点赞并发表评论,说明它对你起作用了,而不是发布另一个解决方案来修复问题。 - Greggory Wiley

0
在我的情况下,我正在使用OpenSSL将证书从Windows导出到Docker内的Linux,并遇到了这个错误。 问题出在OpenSLL的版本上,当我将.pfx文件转换为.crt和.key时,我在Windows上使用的是3.0.x版本,在Linux上安装的是1.1.1版本。在Windows上使用相同版本的OpenSLL后,它就可以工作了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接