此代码在节点v7.9.0(Electron当前使用的版本)中创建一个https服务器,并侦听端口8000:

require('https').createServer(
  {},
  (req, res) => {
    res.writeHead(200);
    res.end('hello world/n');
  }
).listen(8000);

不幸的是,当我在运行服务器的Chrome中访问https://localhost:8000时,得到ERR_SSL_VERSION_OR_CIPHER_MISMATCH。我如何克服这个错误?我如何找出服务器使用的密码以及使用的协议(protocol)(希望是TLS的最新版本)?

编辑在写入本文时,Node的最新稳定版本节点v8.5.0上也会发生此错误。

最佳答案

较晚,但:通常,包括的SSL / TLS服务器和HTTPS服务器需要私钥和(匹配)证书或链才能用于SSL / TLS握手中的公钥算法。有关示例,请参见How to create an HTTPS server in Node.js?

从技术上讲,协议(protocol)中定义了一些不需要密钥和证书的“匿名”密钥交换机制,但是人们普遍认为它们不够安全,默认情况下在OpenSSL(因此也禁用了nodejs)中将其禁用。还有一些使用非公钥算法的密钥交换机制,例如PSK,SRP,Kerberos,但是它们更难使用,并且需要特殊的配置,我不相信可以使用nodejs来完成(而且您当然没有做)。

因此,如果没有密钥和证书,并且没有启用匿名或其他特殊的密钥交换,则服务器支持的密码套件集就是没有元素的空集-并且您进行的每次连接尝试都会失败,因为空集永远不会有非空交集与客户端提供的一组密码套件。

我认为您仍然可以通过查看针对不同ClientHello版本返回的警报的版本来找出其支持的协议(protocol)版本,但是我不确定这样做会有什么用。自2012年发布OpenSSL 1.0.1以来,无论哪种情况,OpenSSL都支持TLS 1.0至1.2,甚至nodejs 7.9.0都比2012年更新很多。OpenSSL还支持SSLv3,但在最新版本中,它已被禁用或从构建中排除默认;如果您的版本仍包含该版本,则不应使用它,因为POODLE攻击会破坏它。 (通常只有在使用仅支持SSLv3而不支持任何TLS的非常老的客户端时,才会发生这种情况。)实际上,低于1.1.0的OpenSSL'支持'SSLv2,因为该代码仍然存在,但默认配置将其禁用; SSLv2长期以来一直被破坏和禁止,您绝对不应使用它。

截至2018年9月,OpenSSL 1.1.1已发布并同时支持TLS 1.3。我不知道是否/何时nodejs使用/支持。

07-27 18:35