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 eu cette exception stacktrace avec 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
J'ai eu une réponse positive 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 pourquoi cela se passe?
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 les instructions 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 poignée de main ssl
System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
Outre la réponse acceptée, d'autres problèmes peuvent également être à l'origine de l'exception. Pour moi, c’est que le certificat n’était pas fiable (par exemple, un certificat auto-signé et non dans le magasin de confiance).
Si le fichier de certificat n’existe pas ou ne peut pas être chargé (par exemple, une faute de frappe dans le chemin) peut, dans certaines circonstances, provoquer la même exception.
Je faisais face au même problème, l’ajout d’un certificat au magasin de confiance a résolu ce problème.
La réponse acceptée n'a pas fonctionné dans ma situation, je ne sais pas pourquoi. Je suis passé de JRE1.7 à JRE1.8 et le problème a été résolu automatiquement. JRE1.8 utilise TLS1.2 par défaut
J'ai eu un problème similaire qui a été résolu en décochant l'option de sécurité avancée Java pour "Utiliser le format ClientHello compatible SSL 2.0.
Cette erreur est générique des bibliothèques de sécurité et peut se produire dans d'autres cas ..___ Si d'autres personnes rencontrent le même problème lors de l'envoi d'e-mails avec javax.mail à un serveur smtp. Ensuite, le code pour forcer un autre protocole définit une propriété comme celle-ci:
prop.put("mail.smtp.ssl.protocols", "TLSv1.2");
//And just in case probably you need to set these too
prop.put("mail.smtp.starttls.enable", true);
prop.put("mail.smtp.ssl.trust", {YOURSERVERNAME});