Pregunta ¿Cómo resolver javax.net.ssl.SSLHandshakeException Error?


Me conecté con VPN para configurar el API de inventario para obtener la lista de productos y funciona bien. Una vez que obtengo el resultado del servicio web y me enlace a la interfaz de usuario. Y también integé PayPal con mi aplicación para hacer el pago exprés cuando realizo una llamada para el pago me enfrento a este error. Yo uso servlet para el proceso de back-end. ¿Alguien puede decir cómo solucionar este problema?

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

75
2017-07-12 04:03


origen


Respuestas:


Primero necesita obtener el certificado público del servidor al que intenta conectarse. Eso se puede hacer de varias maneras, como ponerse en contacto con el administrador del servidor y solicitarlo, usando openssl para descargarloo, como parece ser un servidor HTTP, conectarse a él con cualquier navegador, ver la información de seguridad de la página y guardar una copia del certificado. (Google debería poder decirle exactamente qué hacer para su navegador específico).

Ahora que tiene el certificado guardado en un archivo, debe agregarlo al almacén de confianza de su JVM. A $JAVA_HOME/jre/lib/security/ para JRE o $JAVA_HOME/lib/security para JDKs, hay un archivo llamado cacerts, que viene con Java y contiene los certificados públicos de las bien conocidas Autoridades de Certificación. Para importar el nuevo certificado, ejecute keytool como un usuario que tiene permiso para escribir en los eventos:

keytool -import -file <the cert file> -alias <some meaningful name> -keystore <path to cacerts file>

Lo más probable es que le pida una contraseña. La contraseña predeterminada como se envía con Java es changeit. Casi nadie lo cambia. Después de completar estos pasos relativamente sencillos, se comunicará de forma segura y con la seguridad de que está hablando con el servidor correcto y solo con el servidor correcto (siempre que no pierda su clave privada).


114
2017-07-19 04:08



Ahora resolví este problema de esta manera,

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.OutputStream; 

// Create a trust manager that does not validate certificate chains like the default 

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

            public java.security.cert.X509Certificate[] getAcceptedIssuers()
            {
                return null;
            }
            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
            {
                //No need to implement.
            }
            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
            {
                //No need to implement.
            }
        }
};

// Install the all-trusting trust manager
try 
{
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} 
catch (Exception e) 
{
    System.out.println(e);
}

Por supuesto, esta solución solo debe usarse en escenarios, donde no es posible instalar los certificados requeridos usando keytool p.ej. pruebas locales con certifcates temporales.


14
2017-07-19 03:52



Cuando intentamos conectarnos a una URL,

si el servidor en el otro sitio se está ejecutando en protocolo https y exige que debemos comunicarnos a través de la información provista en el certificado, entonces       tenemos la siguiente opción:

1) solicite el certificado (descargue el certificado), importe este certificado en trustore. Los usos predeterminados de trustore java se pueden encontrar en \ Java \ jdk1.6.0_29 \ jre \ lib \ security \ cacerts, luego, si reintentamos conectarnos a la conexión URL, se aceptaría.

2) En casos comerciales normales, podríamos estar conectando URL internas en organizaciones y sabemos que son correctas.          En tales casos, confía en que es la URL correcta. En tales casos, se puede usar código que no obliga a almacenar el certificado para conectarse a una URL en particular.

para el punto no 2 tenemos que seguir los pasos a continuación:

1) escribir debajo del método que establece HostnameVerifier para HttpsURLConnection que devuelve verdadero para todos los casos, lo que significa que estamos confiando en el trustStore.

  // trusting all certificate 
 public void doTrustToCertificates() throws Exception {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }
                }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
                    System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
                }
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }

2) escriba debajo del método, que llama doTrustToCertificates antes de intentar conectarse a la URL

    // connecting to URL
    public void connectToUrl(){
     doTrustToCertificates();//  
     URL url = new URL("https://www.example.com");
     HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 
     System.out.println("ResponseCode ="+conn.getResponseCode());
   }

Esta llamada devolverá el código de respuesta = 200 significa que la conexión es exitosa.

Para obtener más detalles y ejemplos de muestra, puede consultar URL.


10
2018-03-20 05:54



Creo que estás intentando conectarte a algo utilizando SSL, pero ese algo está proporcionando un certificado que no está verificado por las autoridades certificadoras raíz, como Verisign. En esencia, por defecto, las conexiones seguras solo pueden establecerse si la persona que intenta conectarse sabe las claves de las contrapartes o algún otro verndor como verisign pueden intervenir y decir que la clave pública que se proporciona es correcta.

TODOS los OS confían en un puñado de autoridades de certificación y los emisores de certificados más pequeños deben estar certificados por uno de los grandes certificadores que forman una cadena de certificadores, si entiendes lo que quiero decir ...

De todos modos, volviendo al punto ... Tuve un problema similar al programar un applet de Java y un servidor de Java (espero que algún día escriba un blog completo sobre cómo obtuve toda la seguridad para trabajar :))

En esencia, lo que tenía que hacer era extraer las claves públicas del servidor y almacenarlas en un almacén de claves dentro de mi applet y cuando me conecté al servidor usé este almacén de claves para crear una fábrica de confianza y esa fábrica de confianza para crear el ssl conexión. También hay procedimientos alternativos, como agregar la clave al host de confianza de la JVM y modificar el almacén de confianza predeterminado en el inicio.

Hice esto hace unos dos meses y no tengo el código fuente en este momento ... use Google y debería ser capaz de resolver este problema. Si no puede enviarme un mensaje y puedo proporcionarle el código fuente pertinente para el proyecto ... No sé si esto resuelve su problema ya que no ha proporcionado el código que causa estas excepciones. Además, estaba trabajando con applets pensando que no puedo ver por qué no funciona en Serverlets ...

P.S No puedo obtener el código fuente antes del fin de semana ya que el SSH externo está desactivado en mi oficina :(


0
2017-07-14 17:53



SSLHandshakeException se puede resolver de 2 formas.

  1. Incorporando SSL

    • Obtenga el SSL (preguntando al administrador del sistema de origen, también puede ser descargado por el comando openssl, o cualquier navegador descarga el certificados)

    • Agregue el certificado a truststore (cacerts) ubicado en JRE / lib / seguridad

    • proporcionar la ubicación del almacén de confianza en argumentos vm como "-Djavax.net.ssl.trustStore ="

  2. Ignorando SSL

    Para este # 2, visite mi otra respuesta en otro sitio web de stackoverflow: Cómo iniciar la verificación de SSL Ignorar los errores del certificado SSL con Java


0
2018-03-16 02:04



Ahora resolví este problema de esta manera,

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.OutputStream;
// Create a trust manager that does not validate certificate chains like the 
default TrustManager[] trustAllCerts = new TrustManager[] {
    new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            //No need to implement. 
        }
        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            //No need to implement. 
        }
    }
};
// Install the all-trusting trust manager
try {
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
    System.out.println(e);
}

-3
2017-11-30 01:26