Ottengo errori di connessione visualizzati casualmente quando ci si connette a un server HAProxy tramite SSL. Ho confermato che questi errori si verificano nelle versioni di JDK 1.7.0_21 e 1.7.0_25 ma non con 1.7.0_04 o con 1.6.0_38.
L'eccezione è
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397)
at SSLTest2.main(SSLTest2.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Questi fallimenti si verificano solo quando si utilizza il contesto SSL TLS e non con il contesto predefinito. Il seguente codice viene eseguito in un ciclo mille volte e fallimenti accadere prima del ciclo completa (circa il 2% delle connessioni FAIL):
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, null, null);
SSLSocketFactory factory = sslcontext.getSocketFactory();
SSLSocket socket = (SSLSocket)factory.createSocket("myserver", 443);
//socket.startHandshake();
SSLSession session = socket.getSession();
session.getPeerCertificates();
socket.close();
Se, invece, creo il contesto SSL in questo modo non ho collegamenti fallimenti su una qualsiasi delle versioni di Java che ho citato:
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
il primo modo utilizza SSLContextImpl$TLS10Context
e la successiva utilizza SSLContextImpl$DefaultSSLContext
. Guardando il codice, non vedo alcuna differenza che possa causare l'eccezione.
Perché dovrei ottenere i guasti e quali sono i vantaggi/gli svantaggi dell'utilizzo della chiamata getDefault()
?
Nota: le eccezioni sono state visualizzate per la prima volta utilizzando Apache HttpClient (versione 4). Questo codice è il sottoinsieme più piccolo che riproduce il problema riscontrato con HttpClient.
Ecco l'errore che vedo quando si aggiunge -Djavax.net.debug=ssl
:
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, bad_record_mac
%% Invalidated: [Session-101, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA]
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
main, IOException in getSession(): javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
Un altro pezzo di informazione è che gli errori non si verificano se spengo Diffie-Hellman sul server proxy.
Per favore ri-esegui con -Djavax.net.debug = ssl, handshake e pubblica un output da una corsa fallita. – EJP
Ancora in esecuzione con l'opzione di debug attivata. Aggiornata la domanda con queste informazioni. Qualcuno ha qualche idea? – user2687486
Perché preferisci quattro righe di codice a una? – EJP