2015-03-06 9 views
12

Potrzebuję wykonać żądanie za pomocą protokołu HTTPS. I napisał następujący kod:Brak równorzędnego zamknięcia SSL w Javie

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(); 
     } 
    } 

} 

mam ten wyjątek StackTrace z 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 

mam udany odpowiedź https://google.com ale ten błąd z URL powyżej (https://ancine.band.com.br/xml/pgrt1_dta_20150303.xml).

Przy użyciu PHP, .NET i NodeJS ten URL działa poprawnie.

Ktoś ma pojęcie, dlaczego tak się dzieje?

+0

która wersja Java używasz, aby uruchomić program? –

+3

Uruchom klienta za pomocą '-Djavax.net.debug = ssl, handshake' i opublikuj dane wyjściowe w swoim pytaniu. – EJP

+0

Używam ** środowiska wykonawczego OpenJDK (IcedTea 2.5.4) (7u75-2.5.4-1 ~ trusty1) **. – aneto

Odpowiedz

18

To jest problem protokołu bezpieczeństwa. Używam TLSv1, ale host akceptuje tylko protokoły TLSv1.1 i TLSv1.2, a następnie zmieniłem protokół w Javie zgodnie z instrukcją poniżej:

;

+2

W jaki sposób dowiesz się, która wersja protokołu zabezpieczeń jest akceptowana przez hosta? – testerjoe2

+0

Ta odpowiedź też nie zadziałała. – testerjoe2

2

Oprócz zaakceptowanej odpowiedzi, inne problemy mogą również powodować wyjątek. Dla mnie było to, że certyfikat nie był zaufany (tj. Samopodpisany certyfikat, a nie w zaufanym magazynie).

Jeśli plik certyfikatu nie istnieje lub nie można go załadować (np. Literówka w ścieżce) może --- w pewnych okolicznościach --- spowodować ten sam wyjątek.

+1

Jeśli jest to certyfikat samopodpisany, jak rozwiązać ten błąd? –

+0

Dodaj go do swojego magazynu zaufanych certyfikatów (do całego systemu operacyjnego lub zdefiniuj go podczas uruchamiania JVM za pomocą '-Djavax.net.ssl.trustStore = ...' i '-Djavax.net.ssl.trustStorePassword = ... '.) –

-1

W moim przypadku w adresie URL było tylko białe spacje. Więc najpierw sprawdź ciąg zapytania!

+0

To spowoduje inny błąd. Nie zapobiegnie to ukończeniu uścisku dłoni. – EJP

0

Można ustawić wersje protokołu we właściwości systemu, jak:

przezwyciężyć Błąd SSL handshake

System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2"); 
Powiązane problemy