Le pair SSL s'est arrêté incorrectement en Java
Je dois faire une demande via un protocole HTTPS. J'ai écrit le code suivant:
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();
}
}
}
J'ai obtenu cette stacktrace d'exception avec une 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
J'ai obtenu une réponse réussie de https://google.com mais cette erreur de l'URL ci-dessus (https://ancine.band.com.br/xml/pgrt1_dta_20150303.xml).
En utilisant PHP,. NET et NodeJS cette URL fonctionne bien.
Quelqu'un a une idée de pourquoi cela se produit?
6 answers
C'est un problème de protocole de sécurité. J'utilise TLSv1 mais l'hôte n'accepte que TLSv1.1 et TLSv1. 2 puis j'ai changé le protocole en Java avec l'instruction ci-dessous:
System.setProperty("https.protocols", "TLSv1.1")
;
Vous pouvez définir les versions de protocole dans la propriété système comme suit:
Surmonter l'erreur de connexion ssl
System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
En dehors de la réponse acceptée, d'autres problèmes peuvent également causer l'exception. Pour moi, c'était que le certificat n'était pas approuvé (c'est-à-dire, un certificat auto-signé et non dans le magasin de confiance).
Si le fichier de certificat n'existe pas ou n'a pas pu être chargé (par exemple, une faute de frappe dans path) peut---dans certaines circonstances---provoquer la même exception.
Je faisais face au même problème, pour moi l'ajout d'un certificat au magasin de confiance a résolu ce problème.
J'ai eu un problème similaire qui a été résolu en décochant l'option dans java advanced Security pour "Utiliser le format ClientHello compatible SSL 2.0.
Dans mon cas, il n'y avait que des espaces blancs dans l'URL. Vérifiez donc d'abord la chaîne de requête!