我从一个简单的SSLSocket(Java 8 u45)连接到具有有效证书和域的站点获得证书验证错误。
String hostName = "www.velocityfrequentflyer.com";
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) factory.createSocket(hostName, 443);
SSLSession session = sslsocket.getSession();
java.security.cert.Certificate certicates[] = session.getPeerCertificates();
X509Certificate cert = (X509Certificate) certicates[0]; //the peer certificate
System.out.println("cert.getIssuerDN().getName(): " + cert.getIssuerDN().getName());
System.out.println("cert.getSubjectDN().getName(): " + cert.getSubjectDN().getName());
线程“main”中的异常javax.net.ssl.SSLPeerUnverifiedException:peer未经过身份验证 at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:431) 在sslconnecting.Sslconnecting.main(Sslconnecting.java:33)
使用OpenSSL everthing查看证书似乎包括www。我尝试过此网站的前缀和每个浏览器都对证书感到满意。
openssl s_client -showcerts -connect www.velocityfrequentflyer.com:443 | openssl x509 -noout -text | less
X509v3扩展: X509v3主题替代名称: DNS:www.velocityfrequentflyer.com
有趣的是,如果我将主机更改为velocityfrequentflyer.com并且我真的很难过,那么这是有效的。
有没有办法在没有JAVA检查的情况下调用getPeerCertificates?
我尝试使用具有相同结果的TrustAll SocketFactory。
修改1:
添加startHandshake()后,似乎握手本身失败了:(完全SSL调试:http://pastebin.com/ZKnjrGPR)
线程“main”中的异常javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure 在sun.security.ssl.Alerts.getSSLException(未知来源) 在sun.security.ssl.Alerts.getSSLException(未知来源) at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source) at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) 在sun.security.ssl.SSLSocketImpl.startHandshake(未知来源) 在sun.security.ssl.SSLSocketImpl.startHandshake(未知来源) 在sslconnecting.Sslconnecting.main(Sslconnecting.java:33)
编辑2。
原来该网站需要不安全的密码套件RC4? java.security配置设置为不使用它们。
jdk.tls.disabledAlgorithms = SSLv3的,RC4
然而,只要允许RC4,握手就会完成。它仍然没有解释为什么没有www的握手。前缀。
答案 0 :(得分:0)
再次很奇怪。
如果握手失败,我希望getSession()
抛出相同的异常,因为如果需要,它会调用startHandshake()
AFAIK。
看起来对等人不会说TLSv1.2或者可能想要RC4。
我建议您通过HandshakeCompletionListener
而不是现在的方式获得同行证书。这样会失败的是套接字上的第一个I / O,而不是getPeerCertificate().
在监听器中,如果你不喜欢对等证书,你可以关闭套接字。