這個問題是我相當偏離主題和不明確的問題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