1. java
  2. android
  3. c#
  4. .net
  5. javascript
  6. php
  7. jquery
  8. html
  9. sql

Problema com Java 8 + SSL

Olá.

Estou tentando acessar a api do mercadolivre através de um proxy com o seguinte código:

    @Test
    public void test() throws MalformedURLException, IOException, URISyntaxException {


    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();

    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.db1.com.br", 8080));
    requestFactory.setProxy(proxy);

    String url = "https://api.mercadolibre.com/sites/MLB/categories";

    ClientHttpRequest request = requestFactory.createRequest(new URI(url), HttpMethod.GET);
    ClientHttpResponse response = request.execute();

    System.out.println(new String(ByteStreams.toByteArray(response.getBody())));

    }

Rodei o teste com a JDK 7 e funcionou perfeitamente. Porem com a JDK 8 eu recebo a seguinte mensagem:

javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
    at sun.security.ssl.InputRecord.readV3Record(InputRecord.java:547)
    at sun.security.ssl.InputRecord.read(InputRecord.java:529)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
    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.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
    at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:78)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:52)
    at br.com.db1.anymarket.mercadolivre.integration.MercadoLivreTest.test(MercadoLivreTest.java:178)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    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)

O que estou fazendo de errado?

SOLUÇÃO

Criei a seguinte extensão do SimpleClientHttpRequestFactory:

public class SecureClientHttpRequestFactory extends SimpleClientHttpRequestFactory {

    private static final Logger LOGGER = Logger.getLogger(SecureClientHttpRequestFactory.class);
    private final HostnameVerifier hostNameVerifier;

    public SecureClientHttpRequestFactory(final HostnameVerifier hostNameVerifier) {
    this.hostNameVerifier = hostNameVerifier;
    }

    @Override
    protected void prepareConnection(final HttpURLConnection connection, final String httpMethod) throws IOException {

    // Seta a configuração do socket SSL quando se tratar de uma conexão HTTPs
    if (isHttpsConnection(connection)) {
        ((HttpsURLConnection) connection).setHostnameVerifier(hostNameVerifier);
        ((HttpsURLConnection) connection).setSSLSocketFactory(initSSLContext().getSocketFactory());
    }

    super.prepareConnection(connection, httpMethod);
    }

    private boolean isHttpsConnection(final HttpURLConnection connection) {
    return HttpsURLConnection.class.isInstance(connection);
    }

    private SSLContext initSSLContext() {
    try {
        System.setProperty("https.protocols", "TLSv1");

        final SSLContext ctx = SSLContext.getInstance("TLSv1");
        ctx.init(null, new TrustManager[] { new oracle.net.jndi.TrustManager() }, null);
        return ctx;

    } catch (final Exception ex) {
        LOGGER.error("An exception was thrown while trying to initialize HTTP security manager.", ex);
        return null;
    }
    }
}

E depois utilizei com o RestTemplate do Spring:

    SecureClientHttpRequestFactory requestFactory = new SecureClientHttpRequestFactory(
        org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    requestFactory.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.db1.com.br", "8080")));
    RestTemplate restTemplate = new RestTemplate(requestFactory);
  1. Você vai ver essas setas em qualquer página de pergunta. Com elas, você pode dizer se uma pergunta ou uma resposta foram relevantes ou não.
  2. Edite sua pergunta ou resposta caso queira alterar ou adicionar detalhes.
  3. Caso haja alguma dúvida sobre a pergunta, adicione um comentário. O espaço de respostas deve ser utilizado apenas para responder a pergunta.
  4. Se o autor da pergunta marcar uma resposta como solucionada, esta marca aparecerá.
  5. Clique aqui para mais detalhes sobre o funcionamento do GUJ!

1 resposta

Não é a resposta que estava procurando? Procure outras perguntas com as tags java java8 ssl ou faça a sua própria pergunta.