openssl s_client -cert:证明客户端证书已发送到服务器 [英] openssl s_client -cert: Proving a client certificate was sent to the server
问题描述
背景
我陷入了与服务提供商之间相互指责的局面,该提供商的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屋!