Ignorar el certificado ssl autofirmado usando Jersey Client


Estoy usando la biblioteca cliente de Jersey para ejecutar pruebas contra un servicio rest que se ejecuta en jboss. Tengo https configurado bien en el servidor (que se ejecuta en localhost), utilizando un certificado autofirmado.

Sin embargo, cada vez que corro mis pruebas con la url https obtengo el siguiente error:

com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:131)
    at com.sun.jersey.api.client.Client.handle(Client.java:629)
    at com.sun.jersey.oauth.client.OAuthClientFilter.handle(OAuthClientFilter.java:137)
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:601)
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
    at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:459)
    at test.helper.Helper.sendSignedRequest(Helper.java:174)
    ... And so on

Sé que esto se debe a que mi certificado auto firmado no está en el almacén de claves de Java. ¿Hay alguna manera de que pueda hacer que el Client no verifique la validez del certificado ssl y simplemente lo use de todos modos?

Este código será solo se puede ejecutar contra servidores de prueba, por lo que no quiero ir a la molestia de agregar nuevos certificados de confianza cada vez que configuramos un nuevo servidor de prueba.

Aquí está el código que está haciendo la llamada:

OAuthParameters params = new OAuthParameters();

// baseline OAuth parameters for access to resource
params.signatureMethod(props.getProperty("signature_method"));
params.consumerKey(props.getProperty("consumer_key"));
params.setToken(props.getProperty("token"));
params.setVersion("1.0");
params.nonce();

// OAuth secrets to access resource
OAuthSecrets secrets = new OAuthSecrets();
secrets.consumerSecret(props.getProperty("consumer_secret"));
secrets.setTokenSecret(props.getProperty("token_secret"));

// Jersey client to make REST calls to token services
Client client = Client.create();

// OAuth test server resource
WebResource resource = client.resource(props.getProperty("url"));

// if parameters and secrets remain static, filter cab be added to each web resource
OAuthClientFilter filter = new OAuthClientFilter(client.getProviders(), params, secrets);

// filter added at the web resource level
resource.addFilter(filter);
WebResource.Builder wbr = resource.getRequestBuilder().accept(props.getProperty("accept"));

return wbr.get(ClientResponse.class);

Cualquier ayuda sería muy apreciada.

Author: Chris Salij, 2011-05-18

11 answers

Después de algunas búsquedas y búsquedas a través de algunas preguntas antiguas de stackoverflow, he encontrado una solución en una pregunta anterior:

Aquí está el código que terminé usando.

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){
    public X509Certificate[] getAcceptedIssuers(){return null;}
    public void checkClientTrusted(X509Certificate[] certs, String authType){}
    public void checkServerTrusted(X509Certificate[] certs, String authType){}
}};

// Install the all-trusting trust manager
try {
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, trustAllCerts, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
    ;
}
 77
Author: Chris Salij,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:38

Para Jersey 2.* (Probado en 2.7) y java 8:

import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 

public static Client ignoreSSLClient() throws Exception {

    SSLContext sslcontext = SSLContext.getInstance("TLS");

    sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
    }}, new java.security.SecureRandom());

    return ClientBuilder.newBuilder()
                        .sslContext(sslcontext)
                        .hostnameVerifier((s1, s2) -> true)
                        .build();
}
 42
Author: eitan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 10:00:02

Tuve el mismo problema adn no quería que esto se estableciera globalmente, así que usé el mismo código TrustManager y SSLContext que el anterior, solo cambié el Cliente para que se creara con propiedades especiales

 ClientConfig config = new DefaultClientConfig();
 config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(
     new HostnameVerifier() {
         @Override
         public boolean verify( String s, SSLSession sslSession ) {
             // whatever your matching policy states
         }
     }
 ));
 Client client = Client.create(config);
 10
Author: Ransom Briggs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-09 13:59:55

Este código solo se ejecutará contra servidores de prueba, por lo que no quiero para ir a la molestia de agregar nuevos certificados de confianza cada vez que configuramos un nuevo servidor de prueba.

Este es el tipo de código que eventualmente encontrará su camino en la producción (si no es de usted, alguien más que esté leyendo esta pregunta copiará y pegará los administradores de confianza inseguros que se han sugerido en sus aplicaciones). Es tan fácil olvidar eliminar este tipo de código cuando tienes un fecha límite, ya que no aparece como un problema.

Si le preocupa tener que agregar nuevos certificados cada vez que tenga un servidor de prueba, cree su propia pequeña CA, emita todos los certificados para los servidores de prueba utilizando esa CA e importe este certificado de CA en el almacén de confianza del cliente. (Incluso si no lidia con cosas como la revocación de certificados en línea en un entorno local, esto es ciertamente mejor que usar un administrador de confianza que deja pasar cualquier cosa.)

Hay herramientas para ayudarle a hacer esto, por ejemplo TinyCA o XCA.

 8
Author: Bruno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-14 13:18:26

Dado que soy nuevo en stackoverflow y tengo menos reputación para comentar las respuestas de los demás, estoy poniendo la solución sugerida por Chris Salij con alguna modificación que funcionó para mí.

            SSLContext ctx = null;
            TrustManager[] trustAllCerts = new X509TrustManager[]{new X509TrustManager(){
                public X509Certificate[] getAcceptedIssuers(){return null;}
                public void checkClientTrusted(X509Certificate[] certs, String authType){}
                public void checkServerTrusted(X509Certificate[] certs, String authType){}
            }};
            try {
                ctx = SSLContext.getInstance("SSL");
                ctx.init(null, trustAllCerts, null);
            } catch (NoSuchAlgorithmException | KeyManagementException e) {
                LOGGER.info("Error loading ssl context {}", e.getMessage());
            }

            SSLContext.setDefault(ctx);
 8
Author: Mukesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-10 10:36:46

Para cualquiera en Jersey 2.x sin lambdas, usa esto:

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;

public static Client getUnsecureClient() throws Exception 
{
    SSLContext sslcontext = SSLContext.getInstance("TLS");
    sslcontext.init(null, new TrustManager[]{new X509TrustManager() 
    {
            public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{}
            public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{}
            public X509Certificate[] getAcceptedIssuers()
            {
                return new X509Certificate[0];
            }

    }}, new java.security.SecureRandom());


    HostnameVerifier allowAll = new HostnameVerifier() 
    {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(allowAll).build();
}

Probado con jersey-client 2.11en JRE 1.7.

 4
Author: masi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-27 17:58:14

Simplemente añadiendo el mismo código con las importaciones. También contiene el código no implementado que se necesita para la compilación. Inicialmente tuve problemas para averiguar qué se importó para este código. También se añade el paquete adecuado para el certificado x509. Tengo esto trabajando con ensayo y error:

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;
import javax.ws.rs.core.MultivaluedMap;

 TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

     public java.security.cert.X509Certificate[] getAcceptedIssuers() {
         java.security.cert.X509Certificate[] chck = null;
         ;
         return chck;
     }

     public void checkServerTrusted(X509Certificate[] arg0, String arg1)
             throws CertificateException {
         // TODO Auto-generated method stub

     }

     public void checkClientTrusted(X509Certificate[] arg0, String arg1)
             throws CertificateException {

     }

     public void checkClientTrusted(
             java.security.cert.X509Certificate[] arg0, String arg1)
                     throws java.security.cert.CertificateException {
         // TODO Auto-generated method stub

     }

     public void checkServerTrusted(
             java.security.cert.X509Certificate[] arg0, String arg1)
                     throws java.security.cert.CertificateException {
         // TODO Auto-generated method stub

     }
 } };

 // Install the all-trusting trust manager
 try {
     SSLContext sc = SSLContext.getInstance("TLS");
     sc.init(null, trustAllCerts, new SecureRandom());
     HttpsURLConnection
     .setDefaultSSLSocketFactory(sc.getSocketFactory());
 } catch (Exception e) {
     ;
 }
 3
Author: prakash krishnan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-30 15:40:58

Para Jersey 2.*:

Client client = ClientBuilder.newBuilder()
                .hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                }).build();

-> https://jersey.java.net/documentation/latest/migration.html

 1
Author: Marcelo C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-16 15:59:54

Para Jersey 1.X

    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {

        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {}

        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {}

        public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
            // or you can return null too
            return new java.security.cert.X509Certificate[0];
        }
    }};


    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, trustAllCerts, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
        public boolean verify(String string, SSLSession sslSession) {
            return true;
        }
    });
 0
Author: grep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-29 09:24:55

He notado que cuando se utiliza la configuración del cliente http Apache con un gestor de pooling, la respuesta aceptada no funciona.

En este caso parece que los setters ClientConfig.sslContext y ClientConfig.hostnameVerifier se ignoran silenciosamente. Por lo tanto, si está utilizando la agrupación de conexiones con la configuración del cliente http del cliente apache, debería poder usar el siguiente código para que la verificación ssl se ignore:

  ClientConfig clientConfig = new ClientConfig();
  // ... configure your clientConfig
  SSLContext sslContext = null;
  try {
    sslContext = SSLContext.getInstance("SSL");
    sslContext.init(null, new TrustManager[] {
        new X509TrustManager() {
          @Override
          public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
          }

          @Override
          public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
          }

          @Override
          public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
          }
        }
    }, null);
  } catch (NoSuchAlgorithmException e) {
    //logger.debug("Ignoring 'NoSuchAlgorithmException' while ignoring ssl certificate validation.");
  } catch (KeyManagementException e) {
    //logger.debug("Ignoring 'KeyManagementException' while ignoring ssl certificate validation.");
  }
  Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
      .register("http", PlainConnectionSocketFactory.getSocketFactory())
      .register("https", new SSLConnectionSocketFactory(sslContext, new AbstractVerifier() {
        @Override
        public void verify(String host, String[] cns, String[] subjectAlts) {
        }
      }))
      .build();
  connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
  clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);
  return ClientBuilder.newClient(clientConfig);
 0
Author: Nicholas DiPiazza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-27 16:49:49

Funcionó para mí con este código. Puede ser su para Java 1.7

    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
            // TODO Auto-generated method stub

        }

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
            // TODO Auto-generated method stub

        }
    }};

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        ;
    }
 -3
Author: Tapas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-14 12:34:26