valid unable requested net certification certificates all java ssl ssl-certificate jersey

unable - javax net ssl sslhandshakeexception



Ignore el certificado SSL autofirmado utilizando Jersey Client (11)

Estoy usando la biblioteca de Jersey Client para ejecutar pruebas contra un servicio de descanso que se ejecuta en jboss. Tengo https configurado correctamente en el servidor (ejecutándose en localhost), usando un certificado autofirmado.

Sin embargo, cada vez que ejecuto mis pruebas con la URL https recibo 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 autofirmado no está en el almacén de claves de Java. ¿Hay alguna manera en que pueda hacer que el Client no verifique la validez del certificado SSL y simplemente lo use independientemente?

Este código solo se ejecutará contra los servidores de prueba, por lo que no quiero pasar por la molestia de agregar nuevos certificados de confianza cada vez que configuremos 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.


Este código solo se ejecutará contra los servidores de prueba, por lo que no quiero pasar por la molestia de agregar nuevos certificados de confianza cada vez que configuremos 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 inseguros gerentes de confianza que se han sugerido en sus aplicaciones). Es muy fácil olvidarse de eliminar este tipo de código cuando tiene una 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 CA, emita todos los certificados para los servidores de prueba utilizando esa CA e importe este certificado de CA en su tienda de confianza del cliente. (Incluso si no se ocupa de 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 permite el paso).

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


Como soy nuevo en y tengo menos reputación para comentar las respuestas de los demás, estoy poniendo la solución sugerida por Chris Salij con algunas modificaciones que me funcionaron.

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


Después de algunas búsquedas y búsqueda de algunas viejas preguntas de , encontré una solución en una pregunta de SO:

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


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


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



Para cualquier persona 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.11 en JRE 1.7 .


Solo agregando 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 descubrir qué se importó para este código. También agregando el paquete correcto para el Certificado X509. Funcionó con prueba 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) { ; }


Tenía el mismo problema y no quería que esto se configurara globalmente, así que usé el mismo código TrustManager y SSLContext que el anterior, solo cambié el Cliente para crearlo 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);


Usa lambdas para Jersey 2.x

ClientBuilder.newBuilder() .hostnameVerifier((HostnameVerifier) (h, s) -> { return true; }).build();


trabajado para mí con este código. Puede ser su 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) { ; }