2015-03-06 10 views
12

Ho bisogno di effettuare una richiesta tramite un protocollo HTTPS. Ho scritto il seguente codice:Il peer SSL è stato arrestato in modo errato in Java

import java.net.HttpURLConnection; 
import java.net.URL; 

import org.junit.Test; 

public class XMLHandlerTest { 
    private static final String URL = "https://ancine.band.com.br/xml/pgrt1_dta_20150303.xml"; 

    @Test 
    public void testRetrieveSchedule() { 
     try { 
      HttpURLConnection connection = (HttpURLConnection) new URL(URL).openConnection(); 
      connection.setRequestMethod("HEAD"); 
      int responseCode = connection.getResponseCode(); 
      System.out.println(responseCode); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

} 

ho ottenuto questa eccezione stacktrace con un java.io.EOFException:

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:953) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343) 
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563) 
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) 
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1301) 
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468) 
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338) 
    at br.com.onebr.onesocial.arte1.service.core.scheduler.Arte1XMLHandlerTest.testRetrieveSchedule(Arte1XMLHandlerTest.java:16) 
    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:606) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
Caused by: java.io.EOFException: SSL peer shut down incorrectly 
    at sun.security.ssl.InputRecord.read(InputRecord.java:482) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934) 
    ... 32 more 

ho avuto risposta positiva da https://google.com ma questo errore URL sopra (https://ancine.band.com.br/xml/pgrt1_dta_20150303.xml).

Utilizzo di PHP, .NET e NodeJS che l'URL funziona correttamente.

Qualcuno ha idea del perché questo accada?

+0

quale versione di Java stai usando per eseguire il programma? –

+3

Esegui il tuo client con '-Djavax.net.debug = ssl, handshake' e pubblica l'output nella tua domanda. – EJP

+0

Sto usando ** OpenJDK Runtime Environment (IcedTea 2.5.4) (7u75-2.5.4-1 ~ fidato1) **. – aneto

risposta

18

Questo è un problema del protocollo di sicurezza. Sto usando TLSv1 ma l'host accetta solo TLSv1.1 e TLSv1.2 quindi ho cambiato il protocollo in Java con le istruzioni seguenti:

;

+2

Come scoprire quale versione del protocollo di sicurezza è accettata dall'host? – testerjoe2

+0

Inoltre, questa risposta non ha funzionato per me. – testerjoe2

2

Oltre alla risposta accettata, altri problemi possono causare anche l'eccezione. Per me era che il certificato non era attendibile (cioè, certificato autofirmato e non nel trust store).

Se il file del certificato non esiste, o non può essere caricato (ad es., Errore di battitura nel percorso), in determinate circostanze --- può causare la stessa eccezione.

+1

Se è un certificato autofirmato, come risolvere questo errore? –

+0

Aggiungilo al tuo truststore (a livello di OS o definirne uno quando si avvia JVM con '-Djavax.net.ssl.trustStore = ...' e '-Djavax.net.ssl.trustStorePassword = ... '.) –

-1

Nel mio caso c'era solo uno spazio bianco nell'URL. Quindi controlla prima la stringa di query!

+0

Ciò causerebbe un errore diverso. Non impedirebbe il completamento dell'handshake. – EJP

0

È possibile impostare versioni del protocollo di proprietà di sistema come:

superare errore handshake SSL

System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2"); 
Problemi correlati