这个问题是我非常偏离主题且不明确的问题here的延续。
最近我一直在使用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上。
答案 0 :(得分:2)
从调试输出中可以看到
来自服务器的警报意味着它无法继续握手。确切原因不包含在警报中,但您可能会在服务器端的某些日志文件中看到它。我的猜测是服务器根本不支持客户端接受的这个单一密码。
虽然我不熟悉在Java中处理这些问题,但我建议您简单地抛弃所有代码,这些代码无效地将客户端限制为单个密码。默认情况下,Java应该支持更多的密码,从而减少问题。如果问题仍然存在,请查看服务器端以获取有关服务器不接受客户端的更多信息。
答案 1 :(得分:0)
感谢大家的帮助,但以下是我的解决方案:
在我创建服务器套接字的侦听器线程中,我在keymanagers
中为SSLContext.init()
传入null。这导致服务器无法响应客户端,因此导致握手错误(指向不受支持的密码套件,但实际上是由null密钥管理器引起的)。使用KeyManager
创建和加载KeyManagerFactory
已修复此问题。