use*_*956 6 apache ssl https openssl pki
尝试使用来自自签名CA的客户端证书来使HTTPS会话正常工作.连接应检查所有证书是否有效,包括客户端和服务器端.
我遵循的流程如下:
创建证书颁发机构
openssl genrsa -out CA.key 4096
openssl req -new -key CA.key -out CA.csr
openssl x509 -req -days 365 -in CA.csr -out CA.crt -signkey CA.key
Run Code Online (Sandbox Code Playgroud)创建服务器证书
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr
openssl ca -in server.csr -cert CA.crt -keyfile CA.key -out server.crt
Run Code Online (Sandbox Code Playgroud)创建客户端证书
openssl genrsa -out client.key 4096
openssl req -new -key client.key -out client.csr
openssl ca -in client.csr -cert CA.crt -keyfile CA.key -out client.crt
Run Code Online (Sandbox Code Playgroud)配置Apache
<VirtualHost _default_:443>
SSLEngine on
SSLCertificateFile "server.crt"
SSLCertificateKeyFile "server.key"
SSLCACertificateFile "CA.crt"
<Directory "/var/www">
SSLVerifyClient optional
SSLVerifyDepth 10
SSLOptions +StdEnvVars +ExportCertData
</Directory>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)现在我尝试进行测试连接:
wget \
--post-data 'id=1234' \
--certificate=client.crt \
--ca-certificate=CA.crt \
https://test.example.com:443
Run Code Online (Sandbox Code Playgroud)
wget的结果输出显示(反复),部分:
HTTP request sent, awaiting response... No data received.
Retrying.
Run Code Online (Sandbox Code Playgroud)
从Apache检查SSL错误日志会给我以下消息:
[debug] ssl_engine_io.c(1606): [client xx.xx.xx.xx] total of 41 bytes in buffer, eos=1
[client xx.xx.xx.xx] Requesting connection re-negotiation
[debug] ssl_engine_io.c(1908): OpenSSL: I/O error, 5 bytes expected to read on BIO#80b075190 [mem: 80b0ca003]
[debug] ssl_engine_kernel.c(771): [client xx.xx.xx.xx] Performing full renegotiation: complete handshake protocol (client does support secure renegotiation)
[debug] ssl_engine_kernel.c(1892): OpenSSL: Handshake: start
[debug] ssl_engine_kernel.c(1900): OpenSSL: Loop: SSL renegotiate ciphers
[debug] ssl_engine_kernel.c(1900): OpenSSL: Loop: SSLv3 write hello request A
[debug] ssl_engine_kernel.c(1900): OpenSSL: Loop: SSLv3 flush data
[debug] ssl_engine_kernel.c(1900): OpenSSL: Loop: SSLv3 write hello request C
[info] [client xx.xx.xx.xx] Awaiting re-negotiation handshake
[debug] ssl_engine_kernel.c(1892): OpenSSL: Handshake: start
[debug] ssl_engine_kernel.c(1900): OpenSSL: Loop: before accept initialization
[debug] ssl_engine_io.c(1908): OpenSSL: I/O error, 5 bytes expected to read on BIO#80b075190 [mem: 80b0ca003]
[debug] ssl_engine_kernel.c(1929): OpenSSL: Exit: error in SSLv3 read client hello B
[error] [client xx.xx.xx.xx] Re-negotiation handshake failed: Not accepted by client!?
[debug] ssl_engine_io.c(1650): [client xx.xx.xx.xx] read from buffered SSL brigade, mode 0, 8192 bytes
[debug] ssl_engine_io.c(1725): [client xx.xx.xx.xx] buffered SSL brigade exhausted
[debug] ssl_engine_io.c(1650): [client xx.xx.xx.xx] read from buffered SSL brigade, mode 2, 0 bytes
[info] [client XX:XX:XX:XX::xx] Connection to child 3 established (server register.kiosk.tain.com:443)
[info] Seeding PRNG with 656 bytes of entropy
[debug] ssl_engine_kernel.c(1892): OpenSSL: Handshake: start
[debug] ssl_engine_kernel.c(1900): OpenSSL: Loop: before/accept initialization
Run Code Online (Sandbox Code Playgroud)
运行openssl客户端,看看这里有什么可以帮助的:
openssl s_client \
-showcerts \
-connect test.example.com:443 \
-cert client.crt \
-key client.key \
-CAfile CA.crt
Run Code Online (Sandbox Code Playgroud)
在回复中我看到以下内容:
---
Server certificate
subject=/C=XX/ST=XXXXX/O=XXXX/CN=test.example.com
issuer=/O=XXXX/L=XXXXX/ST=XXXXX/C=SE/CN=XXXX Certificate Authority
---
No client certificate CA names sent
---
SSL handshake has read 3846 bytes and written 519 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Run Code Online (Sandbox Code Playgroud)
"没有发送客户端证书CA名称"看起来与我期望的不同.我想要客户证书.
我哪里错了?
谈论“自签名 CA”并没有什么意义。您的标题(“自签名客户端 SSL 证书 [...] ”)表明您正在谈论自签名客户端证书。您不是:您正在谈论由您自己的 CA 颁发的客户端证书。
您已将SSLVerifyClient指令放在一个Directory部分中,这意味着一旦客户端发出尝试访问该目录的请求,就需要重新协商以获取客户端证书。
由于您的配置中没有DocumentRoot指令,因此不清楚请求是否/会尝试访问此目录(这可能取决于编译选项,具体取决于它的打包方式,但/var/www不是默认值)。
直接放入SSLVerifyClient虚拟主机应该至少可以openssl s_client看到客户端证书请求。修复此问题DocumentRoot可能还不够,因为您需要发出 HTTP 请求来触发重新协商。