【发布时间】:2015-11-10 12:23:03
【问题描述】:
我创建了一个希望能够使用智能卡访问的网站,因此我在该网站上启用了 SSL。当我远程登录到服务器并使用智能卡访问 https 端口上的站点时,一切正常。我收到提示并且网站加载。但是,如果我尝试使用客户端 PC 上的同一张卡访问同一个站点,则会收到 403 Forbidden 错误。
Settings on the server(IIS 7.5) I have implemented or verified:
1) Site is bound to specific port (not 443) with a type of https and a certificate that has a friendly name.
2) SSL settings: Require SSL is checked, Require client certificates is selected (note: if I set it to accept, the site will load for the client but it never prompts for credentials)
3) I have verified that when Require client certificates is set to accept, that the certificate it recognizes in the browser is the correct one (e.g. myserver.com) but as I said then I don't receive the prompt for credentials
4) Anonymous Authentication is enabled, all others disabled
5) applicationhost.config file set the following in location -> system.webserver -> security:
a) sslFlags = "Ssl, SslNegotiateCert, SslRequireCert"
b) under authentication set iisClientCertificateMappingAuthentication to true
6) I have confirmed the necessary certificates exist in the Trusted Root and Personal folders for the Local Computer account.
Settings for the client:
1) I have confirmed the necessary certificates exist and match what the server has in the Trusted Root and Personal folders for the Local Computer account.
2) I have checked that the certificate chain in the browser does not show any errors going down the chain in both IE and Chrome
我创建了一个自签名证书并将其添加到服务器和客户端上的所有证书存储中并收到相同的行为。
使用OpenSSL我取得了以下结果:
openssl s_client -connect myserver.com -CAfile c:\certs\godaddy.pem -servername myserver.com
Loading 'screen' into random state - done
CONNECTED(00000160)
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go D
addy Root Certificate Authority - G2
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http
://certs.godaddy.com/repository/, CN = Go Daddy Secure Certificate Authority - G
2
verify return:1
depth=0 OU = Domain Control Validated, CN = *.myserver.com
verify return:1
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.myserver.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certific
ate Authority - G2
---
Server certificate
-----BEGIN CERTIFICATE-----
...29u1FZGXZnMUZCW5rlmZrkCAiBwDAB0/2t6BhyGh0JxydLWrRzJAZhW33KIem7IC...
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.myserver.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy
.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 2713 bytes and written 673 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: *** edited ***
Session-ID-ctx:
Master-Key: *** edited ***
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1439825381
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
read:errno=10054
OpenSSL 结果有一个部分显示“未发送客户端证书 CA 名称”,在我添加 -CAfile 选项之前,我收到了“无法获取本地颁发者证书”的验证 20 错误。
更新 OpenSSL 结果:
弄清楚如何使用调试功能,从我在这里看到的内容来看,只要我传入 CAfile 路径,它似乎就可以正确协商 SSL 并使用正确的证书。
openssl s_client -connect myserver.com:10168 -state -debug -CAfile c:\certs\godaddy.pem -servername myserver
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certs.godaddy.com/repository/, CN = Go Daddy Secure Certificate
Authority - G2
verify return:1
depth=0 OU = Domain Control Validated, CN = *.myserver.com
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.myserver.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certific
ate Authority - G2
---
Server certificate
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.myserver.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy
.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 2713 bytes and written 643 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: ***
Session-ID-ctx:
Master-Key: ***
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1439919398
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
read from 0x2dd5b0 [0x2f06d3] (5 bytes => -1 (0xFFFFFFFF))
read:errno=10054
write to 0x2dd5b0 [0x2f4c23] (37 bytes => -1 (0xFFFFFFFF))
附加 openssl 命令:
openssl s_client -connect yourip:443 -prexit
...在 SO site here 上找到的确实证明了在可接受的证书名称列表中是 Go Daddy 2 类证书颁发机构 CA;但是,我没有看到 *.myserver.com。由于 *.myserver.com 链接到 Go Daddy 2 类证书颁发机构 CA,这似乎是一个正常的过程,如 by this site here 所示。在我的本地电脑和服务器上,Go Daddy 证书存在于 Trusted Root 和 Intermediate CA 文件夹中。
更新-netsh:
我还尝试了netsh http add sslcert certhash= appid= clientcertnegotiation=enable,它成功执行但没有成功。
WIRESHARK 信息更新:
如果我在本地 PC 上使用 Wireshark 来查看特定于服务器的流量(显示过滤器设置为搜索 ip.addr 或 ssl),我根本看不到 SSL 生成的任何流量。没有客户端或服务器 Hello 或证书条目。我确实在前三个 SYN、SYN/ACK 和 ACK 数据包中验证了 IP 地址和端口是正确的值。
当我在服务器上运行 Wireshark 时,我看不到任何 SSL 流量,或者特别是来自我的 IP 地址。但是,如果我直接在服务器上运行 Wireshark 和我的 SSL 网站,该站点确实会解析、运行并提示输入凭据,但我发现证书 id-at-commonName 等于一个不同于我分配给该站点的证书( *.myserver.com) 是 *.vo.msecnd.net,根据我的研究属于 Microsoft 的 Baltimore CyberTrust Root 证书。
更新 - 修复证书
按照说明on this site修复证书并排除它有问题。我没有 Entrust 证书,但底部的说明是一样的。
为什么我没有看到客户您好?如何解决缺少 SSL 握手的问题?
我用来尝试解决问题的一些 SO 网站包括:
OpenSSL errno 10054,connection refused
OpenSSL: unable to get local issuer certificate
IIS 7.5 site with SSL fails, site without SSL works
解决方案:
似乎证书修复和设置客户端证书协商的组合起到了作用,但只有在我重新启动服务器之后。
【问题讨论】: