OpenSSL 连接:警报内部错误

Mar*_*vič 7 ssl openssl

我在使用 SNI 的单个服务器上运行了 100 个 HTTPS 服务。(实际上,我无权访问它们。这是一个分配。我只知道它们的域名N.xxx.yy,其中 N 的范围是 00 到 99。)分配的目标是评估每个连接的安全性这些服务器。所以一些服务器包含过期的证书,带有错误 CN 的证书等。

我的问题是我无法通过某些服务器上的握手。我已经使用 OpenSSL 用 C++ 编写了自己的应用程序,但我也尝试过使用openssl s_client. 这是我连接到服务器的方式:

openssl s_client -host N.xxx.yy -port 443 -verify 1 -servername N.xxx.yy -CAfile assignment-ca.pem
Run Code Online (Sandbox Code Playgroud)

这就是我得到的:

139625941858168:error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error:s3_pkt.c:1493:SSL alert number 80
139625941858168:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
Run Code Online (Sandbox Code Playgroud)

在 Wireshark 中,我看到客户端发送了ClientHello,服务器响应ServerHello(选择 TLSv1.2 和ECDHE-RSA-AES256-GCM-SHA384Certificate,然后它向我Alert发送了包含Internal Error (80).

在尝试了不同的事情后,我发现如果我跑s_client-tls1或者-tls1_1我可以成功地通过握手。-tls1_2不起作用。更奇怪的是,即使协商了 TLSv1.2,通过 Chrome/Firefox/任何其他浏览器的连接也能成功。从我所见,Chrome 发送的密码列表与我不同,或者s_client即使修改密码列表以匹配 Chrome 中的密码列表(并确保服务器选择ECDHE-RSA-AES128-GCM-SHA256),它也不起作用。Chrome 正在发送这些 TLS 扩展,我没有,但其中大部分似乎是空的:

Unknown 47802
renegotiation_info
Extended Master Secret
signed_certificate_timestamp
status_request
Application Layer Protocol Negotiation
channel_id
Unknown 6682
Run Code Online (Sandbox Code Playgroud)

有人能解释一下这里发生了什么吗?不幸的是,我无法在服务器端调试它,所以这就是我所知道的。

更新:

在玩弄伪造的ClientHello消息后,我设法将其追踪到signature_algorithms扩展名。我的应用程序并s_client提供,SHA384 + {RSA,DSA,ECDSA}但如果我删除这些并保留SHA256 + {RSA,DSA,ECDSA},就像 Chrome 一样,它可以工作并且我Server Key Exchange成功收到消息。可能是服务器以某种方式不支持它,而不是提供有意义的错误消息,它只是意外结束并给我这个内部错误?

更新 2:

我在 RFC5246 中找到了为什么它适用于 1.2 之前的 TLS 版本的答案。上一个更新中的问题仍然成立。

Note: this extension is not meaningful for TLS versions prior to 1.2.
   Clients MUST NOT offer it if they are offering prior versions.
   However, even if clients do offer it, the rules specified in [TLSEXT]
   require servers to ignore extensions they do not understand.
Run Code Online (Sandbox Code Playgroud)

Ari*_*ion 1

既然您写道,-tls1_2 does not work我假设您和/或服务器使用较旧的 openssl 库。撰写本文时的当前版本是 1.1.0e

自 0.9.8 以来,有相当多的修复,这些修复通常可以在旧系统上看到。

对于版本 1.0.1有这个修复,这听起来像你的问题:

 `Some servers which support TLS 1.0 can choke if we initially indicate
 support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA
 encrypted premaster secret. As a workaround use the maximum permitted
 client version in client hello, this should keep such servers happy
 and still work with previous versions of OpenSSL.`
Run Code Online (Sandbox Code Playgroud)

也许还值得注意

Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections.

因此,我建议更新您的 openssl 版本,如果服务器不受您的控制,我会坚持您已经找到的设置。