如果我收到无效公钥错误,是否意味着我错误地安装了证书

如果我收到无效公钥错误,是否意味着我错误地安装了证书

我为客户创建了一个 API(在 nginx 服务器上运行,如果您认为有任何相关的详细信息,请告诉我),他们在尝试调用我的服务时收到此错误:

Notice: SSL certificate problem: self signed certificate in certificate chain 
in /usr/local/zend/apache2/htdocs/PefcSCS/components/ \
com_pefcscs/views/simplesearchs/tmpl/default.php on line 9

我无法重现此错误,也没有自签名证书。查看日志后我发现:

$ sudo tail -n 100 /var/log/nginx/error.log
2014/05/04 07:17:09 [crit] 24027#0: *844 SSL_do_handshake() failed 
(SSL: error:05066066:Diffie-Hellman routines:COMPUTE_KEY:invalid 
public key error:1408B005:SSL routines:SSL3_GET_CLIENT_KEY_EXCHANGE:DH lib) 
while SSL handshaking, client: xx.169.xx.141, server: 0.x.0.x:443

上面写着:invalid public key error。这是否意味着他们提供了无效的公钥?有人能解释一下错误的含义以及如何解决这个问题吗?谢谢。

编辑:PS 我只是假设这两点是相关的,这可能是一个巧合,我推断失败的公钥交换和我的客户奇怪的错误之间存在联系,表明我们有一个自签名证书。

答案1

可能还没有答案,但我可以在评论中解释得更清楚:

该错误代码(和字符串)是关于迪菲一赫尔曼公钥。除非您使用的是静态 DH,这非常不寻常——我从未见过公共 CA 颁发 DH 证书——这必须是客户端的 DHE 密码套件的临时 DH 密钥。如果它无效,则表明客户端 SSL 堆栈中存在一些非常奇怪的问题,会话受到“攻击”(或至少是损坏),或者服务器中的 DH 参数受到破坏——所有这些都不应该发生。如果客户端声称“自签名证书”而您没有使用,那就是另一个不应该相关的问题,但可能是由于一些奇怪的错误。

客户端似乎是用 PHP 编写的,我对此并不熟悉,但我猜它很可能使用 openssl 来建立客户端 SSL 连接(在本例中是与您建立连接)(就我所知,nginx 在服务器端使用 openssl 也是如此)。如果您将服务器配置为提供包括根证书在内的完整证书链,而 openssl 客户端在其使用的信任库中没有该根证书(这可能是可配置的),它可能会令人困惑地报告“自签名证书”,而不是更确切的“不受信任的根证书”。

如果我没记错的话,它是 openssl,那么(你问)客户端人员是否可以尝试使用命令行 openssl 连接到你s_client,使用他们的程序正在使用的相同信任库和相同的密码列表(可能是默认的)——看看是否会出现任何错误,如果出现错误,s_client 会给出(更详细的)错误信息吗?换句话说,命令应该是这样的

  openssl s_client -connect $yourhost:$yourport -CAfile $file_if_any -CApath $dir_if_any -cipher $string_if_any

(如果确实连接,只需按 Control-D 退出而不发送任何内容。)如果s_client说类似的话verify error: ... self-signed,他们应该修复他们正在使用的信任库以包含您正在使用的链的根证书。(如果他们不能或不想修改他们当前使用的信任库,这可能意味着更改为使用不同的信任库。)

与此同时,您的服务器中配置了什么(如果有的话) ?以防万一,ssl_dhparam请尝试在该文件上使用 openssl ,尽管那里的任何错误都应该在握手的早期步骤中失败。dhparam -check -noout

当其他(客户端)连接成功时,您可以检查它们是否协商 DHE 吗?请记住,RSA 证书(迄今为止最常见的证书)可以支持纯 RSA DHE-RSA 和 ECDHE-RSA 密码。某些客户端可以显示所选密码,特别是如果您的服务器接受浏览器 https 请求,则大多数浏览器都可以显示所选密码。我自己不使用 nginx,但是http://osdir.com/ml/nginx/2010-07/msg00033.html表示它可以记录这个。 s_client总是告诉你密码,以及许多其他东西。

如果问题仍然存在,您、他们或其他人能否使用 wireshark/tshark、tcpdump 或类似工具捕获失败连接的网络?这将确认所使用的密码套件和其他选项,并显示失败前的 DHE 交换,这至少应该可以缩小问题范围。在我看来,最简单的查看方法是在 wireshark 中显示(即使您使用其他工具捕获),展开 ServerHello 并获取 CipherSuite,然后展开 ServerKeyExchange 和 ClientKeyExchange 并获取所有详细信息。

相关内容