这个问题是我相当偏离主题和不明确的问题here的延续。Java SSL握手失败
最近我一直在使用的SSLSockets,不管我做什么,我不断收到以下错误:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at com.gmail.socraticphoenix.plasma.net.client.ClientThread.run(ClientThread.java:72)
至于现在,我使用的是信任所有证书一的TrustManager(用于测试目的),它看起来像这样:
public static TrustManager[] getAllTrusting() {
return new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
};
}
创建监听套接字的代码是:
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, NetUtility.getAllTrusting(), new SecureRandom());
SSLServerSocketFactory factory = sslContext.getServerSocketFactory();
SSLServerSocket socket = (SSLServerSocket) factory.createServerSocket(this.server.getPort());
socket.setUseClientMode(false);
socket.setSoTimeout(500);
客户端套接字的代码是像这样:
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, NetUtility.getAllTrusting(), new SecureRandom());
SSLSocketFactory factory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) factory.createSocket(this.client.getTargetHost(), this.client.getTargetPort());
socket.setUseClientMode(true);
socket.startHandshake();
我试过设置的协议,启用和禁用会话创建和设置密码套件。我非常难过。完整的调试跟踪在pastebin。另外,作为一个说明,当我用普通的,不安全的套接字代替侦听器和客户端代码时,test class输出预期的结果,这意味着该代码是问题所在。
TL; DR handshake_failure,请大家帮忙!
编辑1: 为了澄清,服务器和客户端在同一台机器上运行在同一个JDK上。
客户端只支持一个密码套件:'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256'。 Ergo这不是真正的代码。你的阅读时间太短。注意:不要在非兼容的TrustManager实现中浪费时间。您需要在此处发布调试跟踪。 – EJP
@EJP我不明白你的意思是“这不是真正的代码......”另外,你说什么意思读取超时太短?我唯一的超时是在监听套接字上设置accept()超时......另外,我希望能够有一个TrustManager将所有的证书信任为我正在构建的框架的一个选项。 –
它不能是真正的代码,因为客户端只支持一个密码套件,并且在您的文章中没有密码套件设置代码。默认情况下,Java客户端将支持几十个密码套件。 '超时太短'意味着'超时太短'。半秒钟是不够的一个数量级。如果没有连接不能等待几秒钟,您还需要做什么? – EJP