openssl s_client -cert:证明客户端证书已发送到服务器 [英] openssl s_client -cert: Proving a client certificate was sent to the server

查看:204
本文介绍了openssl s_client -cert:证明客户端证书已发送到服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

我陷入了与服务提供商之间相互指责的局面,该提供商的API受SSL服务器和客户端证书保护.

  • 我已经生成了CSR,并从公共CA(在这种情况下为GoDaddy)获得了证书,并将证书和CA链提供给了服务提供商.
  • 据说他们已经将CA和我的客户证书加载到了他们的网关中.
  • 我正在使用openssl s_client -connect ... -cert ... -key ...
  • 进行最基本的水平测试
  • 提供者告诉我,他们的日志表明我的请求根本不包含客户端SSL证书.
  • 奇怪的是,在SSL握手期间提供的可接受的客户端证书CA名称"列表中确实出现了适合我的证书的CA颁发者.
  • 作为参考,我创建并提供给他们进行测试的自签名证书确实可以正常工作.

示例(失败)请求

[shell ~]$ openssl s_client -connect host:443 -cert cert_and_key.pem -key cert_and_key.pem -state -quiet
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 **SNIP**
verify return:1
depth=1 **SNIP**
verify return:1
depth=0 **SNIP**
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write certificate verify A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL3 alert read:fatal:unknown CA
SSL_connect:failed in SSLv3 read finished A
140011313276744:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1197:SSL alert number 48
140011313276744:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:

我看到的SSL3 alert read:fatal:unknown CA错误是服务器无法识别我(实际上)提供的证书的颁发者.但是,提供商向我保证" CA证书已正确加载,否则我无法说服它们.

问题

因此,撇开其他(广泛的)故障排除步骤,我真正想知道的是:

openssl s_client中是否有一些可用输出明确表明客户端证书不是服务器所请求的,而是在SSL握手期间实际上已向服务器发送 ?

我已经尝试过-state-msg-debug-trace选项,但是没有足够的背景来解释输出.

EJP的答案表明,我提供的示例输出足以通过write client certificate A进行证明,但是无论是否在命令行上使用了-cert选项,该输出都会出现,因此,这并不表示证书已被使用. 发送.

解决方案

为了验证正在将客户端证书发送到服务器,您需要分析-state-debug标志组合的输出

首先作为基准,尝试运行

$ openssl s_client -connect host:443 -state -debug

您将获得大量输出,但我们感兴趣的行如下所示:

SSL_connect:SSLv3 read server done A
write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
0000 - 16 03 01 00 07 0b 00 00-03                        .........
000c - <SPACES/NULS>
SSL_connect:SSLv3 write client certificate A

这里发生了什么:

  • -state标志负责显示上一节的结尾:

    SSL_connect:SSLv3 read server done A  
    

    这仅对于帮助您在输出中找到自己的位置很重要.

  • 然后-debug标志显示下一步要发送的原始字节:

    write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
    0000 - 16 03 01 00 07 0b 00 00-03                        .........
    000c - <SPACES/NULS>
    

  • 最后,-state标志再次报告-debug刚刚回显的步骤的结果:

    SSL_connect:SSLv3 write client certificate A
    

因此,换句话说:s_client完成读取从服务器发送的数据,并以无客户端证书" 消息的形式发送12字节到服务器. >


如果您重复测试,但是这次包括如下所示的-cert-key标志:

$ openssl s_client -connect host:443 \
   -cert cert_and_key.pem \
   -key cert_and_key.pem  \
   -state -debug

您的已完成读取服务器" 行和写入客户端证书" 行之间的输出将更长,代表您的客户端证书的二进制形式:

SSL_connect:SSLv3 read server done A
write to 0x7bd970 [0x86d890] (1576 bytes => 1576 (0x628))
0000 - 16 03 01 06 23 0b 00 06-1f 00 06 1c 00 06 19 31   ....#..........1
(*SNIP*)
0620 - 95 ca 5e f4 2f 6c 43 11-                          ..^%/lC.
SSL_connect:SSLv3 write client certificate A

1576 bytes本身就是一个很好的指示,表明证书已传输,但是最重要的是,右栏将显示证书的一些易于理解的部分:您应该能够识别出您的证书的CN和发行者字符串就在其中.

Background

I am stuck in a finger-pointing match with a service provider with an API protected by SSL server and client certificates.

  • I have generated a CSR, obtained a certificate from a public CA (GoDaddy in this case) and provided the certificate and CA chain to the service provider.
  • They have supposedly loaded the the CA and my client certificate into their gateway.
  • I am working with the most basic level tests using openssl s_client -connect ... -cert ... -key ...
  • The provider tells me that their logs suggest my requests do not include a client SSL certificate at all.
  • Strangely, the proper CA issuer for my certificate does appear in list of "Acceptable client certificate CA names" provided during the SSL handshake.
  • For reference, a self-signed certificate I created and provided to them for testing does in fact work properly.

A sample (failed) request

[shell ~]$ openssl s_client -connect host:443 -cert cert_and_key.pem -key cert_and_key.pem -state -quiet
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 **SNIP**
verify return:1
depth=1 **SNIP**
verify return:1
depth=0 **SNIP**
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write certificate verify A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL3 alert read:fatal:unknown CA
SSL_connect:failed in SSLv3 read finished A
140011313276744:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1197:SSL alert number 48
140011313276744:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:

My reading of the SSL3 alert read:fatal:unknown CA error is that the server does not recognize the issuer of the certificate I am (in fact) providing. However, the provider "assures" me that the CA certificates are loaded properly and I have been unable to convince them otherwise.

Question

So, putting other (extensive) troubleshooting steps aside, what I'd really like to know is:

Is there some output available from openssl s_client that conclusively shows that a client certificate wasn't just requested by the server, but in fact was transmitted to the server during the SSL handshake?

I have experimented with the -state, -msg, -debug and -trace options, but don't have the background necessary to interpret the output.

EJP's answer suggests that the sample output I provided is proof enough with the write client certificate A, but this output appears regardless of whether the -cert options was used on the command line or not, so it's not indicative that a certificate was sent.

解决方案

In order to verify a client certificate is being sent to the server, you need to analyze the output from the combination of the -state and -debug flags.

First as a baseline, try running

$ openssl s_client -connect host:443 -state -debug

You'll get a ton of output, but the lines we are interested in look like this:

SSL_connect:SSLv3 read server done A
write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
0000 - 16 03 01 00 07 0b 00 00-03                        .........
000c - <SPACES/NULS>
SSL_connect:SSLv3 write client certificate A

What's happening here:

  • The -state flag is responsible for displaying the end of the previous section:

    SSL_connect:SSLv3 read server done A  
    

    This is only important for helping you find your place in the output.

  • Then the -debug flag is showing the raw bytes being sent in the next step:

    write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
    0000 - 16 03 01 00 07 0b 00 00-03                        .........
    000c - <SPACES/NULS>
    

  • Finally, the -state flag is once again reporting the result of the step that -debug just echoed:

    SSL_connect:SSLv3 write client certificate A
    

So in other words: s_client finished reading data sent from the server, and sent 12 bytes to the server as (what I assume is) a "no client certificate" message.


If you repeat the test, but this time include the -cert and -key flags like this:

$ openssl s_client -connect host:443 \
   -cert cert_and_key.pem \
   -key cert_and_key.pem  \
   -state -debug

your output between the "read server done" line and the "write client certificate" line will be much longer, representing the binary form of your client certificate:

SSL_connect:SSLv3 read server done A
write to 0x7bd970 [0x86d890] (1576 bytes => 1576 (0x628))
0000 - 16 03 01 06 23 0b 00 06-1f 00 06 1c 00 06 19 31   ....#..........1
(*SNIP*)
0620 - 95 ca 5e f4 2f 6c 43 11-                          ..^%/lC.
SSL_connect:SSLv3 write client certificate A

The 1576 bytes is an excellent indication on its own that the cert was transmitted, but on top of that, the right-hand column will show parts of the certificate that are human-readable: You should be able to recognize the CN and issuer strings of your cert in there.

这篇关于openssl s_client -cert:证明客户端证书已发送到服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆