¿Cómo solucionar el error javax.net.ssl.SSLHandshakeException?

Resuelto selladurai asked hace 13 años • 5 respuestas

Me conecté con VPN para configurar la API de inventario para obtener la lista de productos y funciona bien. Una vez que obtengo el resultado del servicio web y me vinculo a la interfaz de usuario. Y también integré PayPal con mi aplicación para realizar pago exprés. Cuando hago una llamada de pago, me encuentro con este error. Utilizo 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
selladurai avatar Jul 12 '11 11:07 selladurai
Aceptado

Primero, debe obtener el certificado público del servidor al que intenta conectarse. Esto se puede hacer de varias maneras, como contactar al administrador del servidor y solicitarlo, usar OpenSSL para descargarlo o, dado que parece ser un servidor HTTP, conectarse a él con cualquier navegador y ver la información de seguridad de la página. y guardar una copia del certificado. (Google debería poder decirle exactamente qué hacer con su navegador específico).

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

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

Lo más probable es que te solicite una contraseña. La contraseña predeterminada que viene con Java es changeit. Casi nadie lo cambia. Después de completar estos pasos relativamente simples, 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 pierdan su clave privada).

Ryan Stewart avatar Jul 19 '2011 04:07 Ryan Stewart

Siempre que intentamos conectarnos a una URL,

Si el servidor del otro sitio se ejecuta en el protocolo https y exige que nos comuniquemos a través de la información proporcionada en el certificado, entonces tenemos la siguiente opción:

1) solicite el certificado (descargue el certificado), importe este certificado en el almacén de confianza. Los usos predeterminados de Trustore Java se pueden encontrar en \Java\jdk1.6.0_29\jre\lib\security\cacerts, luego, si volvemos a intentar conectarnos a la URL, se aceptará la conexión.

2) En casos comerciales normales, es posible que nos estemos conectando a URL internas de las organizaciones y sepamos que son correctas. En tales casos, usted confía en que es la URL correcta. En los casos anteriores, se puede utilizar el código que no obligará a almacenar el certificado para conectarse a una URL en particular.

Para el punto no 2 tenemos que seguir los siguientes pasos:

1) escriba el siguiente método que configura HostnameVerifier para HttpsURLConnection, que devuelve verdadero en todos los casos, lo que significa que confiamos en 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 el método siguiente, que llama a 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, lo que significa que la conexión se realizó correctamente.

Para obtener más detalles y un ejemplo de muestra, puede consultar la URL .

Shirish Bari avatar Mar 20 '2014 05:03 Shirish Bari