确定服务器是否正在使用 openssl s_client 请求客户端证书

信息安全 openssl
2021-08-19 23:40:31

openssl用来连接到服务器以检测它们是否需要客户端证书。

目前我正在使用这个命令:

openssl s_client -connect pokyloky.com:5222 -state 2>&1 | grep 'server certificate request' 

SSL_connect:SSLv3 read server certificate request A

我很惊讶简单地使用:

openssl s_client -connect pokyloky.com:5222 

不直接表明已请求客户端证书。握手错误:

139843101763232:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1262:SSL alert number 40
139843101763232:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:

但它没有明确说明握手失败的原因。

为什么没有openssl s_connect明确指出服务器请求了证书,握手失败了呢?

2个回答

该行为不是 TLS v1.2 的一部分

但它没有明确说明握手失败的原因。

它不能。它没有被定义为 (TLS v1.2) 协议的一部分。

当服务器或客户端决定中止连接时,他们可以从多alert条消息中选择一条。

一条Alert消息如下所示

struct {
      AlertLevel level;
      AlertDescription description;
} Alert;

AlertLevel 是一个字节宽,只有两种状态:

enum { warning(1), fatal(2), (255) } AlertLevel;

并且AlertDescription也是一个字节宽。在 256 个可能的原因代码中,只有大约 30 个被分配和使用在这 30 个中,根本没有一个符合“嘿,我告诉过你我想要一个客户证书,你为什么不给我一个?!?” -账单。

(虽然听起来它可能适合,no_certificate_RESERVED(41)但用于其他用途。即在 SSLv3.0 中,它用于另一个方向:让客户端告诉服务器“对不起,我不能给你客户端证书。” )

现在是更深层次的问题“如果还有大量未使用的代码点,定义这样的原因代码是否有意义?而不仅仅是困难的、很大程度上无法解释的失败?” 我的回答很简单:“我不知道。”

我看不出有这样的警报会如何使协议变弱,但加密很棘手,我不确定。

负载均衡器提供友好的错误消息

但是如果你想给出一个友好的错误信息呢?

AFAIK,那么您必须使用诸如逻辑之类的负载均衡器做一些复杂的事情,并且最初只允许无客户端证书的连接,然后立即重定向到错误页面。Apache 可以使用与此类似的规则来做这样的事情:

RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
RewriteRule .* /help/ssl-client-auth-required.html [L]

IIS 定义了一个名为403.7 Forbidden: Client Certificate Required. 我认为这是一个聪明的举动(至少比失败要好),即使of是非标准的.7403.7我认为错误消息属于 TLS 层而不是 HTTP 层。

您可以通过添加标志-trace来查看协议的详细输出。文件指出:

-痕迹

show verbose trace output of protocol messages. OpenSSL needs to be compiled with enable-ssl-trace for this option to work.

当然,您可以使用标志-state-debug-msg来检索有关所选协议如何工作以及 openssl 经历的状态的大量信息:

-状态

prints out the SSL session states.

-调试

print extensive debugging information including a hex dump of all traffic.

-味精

show all protocol messages with hex dump.