java - consumir - Creación de ruta de PKIX fallida: no se puede encontrar una ruta de certificación válida para el objetivo solicitado
web service ssl (8)
Aquí está la solución que utilicé para instalar el certificado público de un sitio en el almacén de claves de los sistemas para su uso.
Descargue el certificado con el siguiente comando:
Unix, Linux, Mac
openssl s_client -connect [host]:[port|443] < /dev/null | sed -ne ''/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'' > [host].crt
ventanas
openssl s_client -connect [host]:[port|443] < NUL | sed -ne ''/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'' > [host].crt
Eso creará un crt que se puede usar para importar a un almacén de claves.
Instale el nuevo certificado con el comando:
keytool -import -alias "[host]" -keystore [path to keystore] -file [host].crt
Esto le permitirá importar el nuevo certificado del sitio que está causando la excepción.
Estoy llamando a algún servicio web HTTPS que el siguiente cliente:
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
/**
* Handles http and https connections. It sends XML request over http (or https)
* to SOAP web service and receive the XML reply.
*
* @author mhewedy
* @date 30.10.2010
*/
public class HttpWSXmlClient
{
private final String ws_url;
private byte[] requestData;
public HttpWSXmlClient(String wsUrl)
{
this.ws_url = wsUrl;
}
public void readRequest(String xmlRequestFilePath)
{
try
{
InputStream istream = new FileInputStream(xmlRequestFilePath);
byte[] data = stream2Bytes(istream);
istream.close();
this.requestData = data;
} catch (Exception e)
{
throw new RuntimeException(e.getMessage());
}
}
/**
*
* @param ps
* PrintStream object to send the debugging info to.
* @return
* @throws IOException
*/
public byte[] sendAndRecieve(PrintStream ps) throws IOException
{
if (requestData == null)
throw new RuntimeException(
"the request data didn''t initialized yet.");
if (ps != null)
ps.println("Request:/n" + new String(requestData));
URL url = new URL(ws_url);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
// or HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("content-type", "text/xml");
connection.connect();
OutputStream os = connection.getOutputStream();
os.write(requestData);
InputStream is = connection.getInputStream();
byte[] rply = stream2Bytes(is);
if (ps != null)
ps.println("Response:/n" + new String(rply));
os.close();
is.close();
connection.disconnect();
return rply;
}
public byte[] sendAndRecieve() throws IOException
{
return sendAndRecieve(null);
}
private byte[] stream2Bytes(InputStream istream) throws IOException
{
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
int c;
while ((c = istream.read()) != -1)
{
if (c != 0x0A && c != 0x0D) // prevent new line character from being
// written
{
if (c == 0x09)
c = 0x20; // prevent tab character from being written,
// instead write single space char
outstream.write(c);
}
}
byte[] ret = outstream.toByteArray();
outstream.close();
return ret;
}
}
Prueba:
public class Test
{
private static final String WS_URL = "https://some_server/path/to/ws";
public static void main(String[] args) throws Exception
{
HttpWSXmlClient client = new HttpWSXmlClient(WS_URL);
client.readRequest("request.xml");
client.sendAndRecieve(System.out);
}
}
Obtuve el siguiente resultado:
Exception in thread "Main Thread" 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.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1591)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1107)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:415)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)
at com.se.swstest.HttpWSXmlClient.sendAndRecieve(HttpWSXmlClient.java:63)
at com.se.swstest.Test.main(Test.java:11)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:285)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:191)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1014)
... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:280)
... 18 more
¿Necesito algún certificado en jdk / jre / lib / security ??? Además, tengo xxx_IE.crt y xxx_FX.crt (para Firefox e IE respectivamente, y no funcionan para el cliente Java anterior, entonces ¿necesito un certificado específico para el cliente de Java?
Gracias.
Debes establecer el certificado para golpear esta url. utilice el código siguiente para establecer el almacén de claves:
System.setProperty("javax.net.ssl.trustStore","clientTrustStore.key");
System.setProperty("javax.net.ssl.trustStorePassword","qwerty");
En Mac OS tuve que abrir el certificado autofirmado del servidor con la herramienta System Keychain Access, importarlo, dobubleclic y seleccionar "Always trust" (aunque establecí lo mismo en el importador). Antes de eso, por supuesto, ejecuté la clave java con -importcert para importar el mismo archivo al almacenamiento cacert.
Había golpeado esto cuando estaba tratando de iniciar una solicitud SOAP desde el código Java. Lo que funcionó para mí fue:
Obtenga el certificado del servidor presionando la URL en el navegador: http://docs.bvstools.com/home/ssl-documentation/exporting-certificate-authorities-cas-from-a-website Este enlace contiene todos los pasos para obtener el servidor certificado
Una vez que tenga el certificado del servidor, siga http://java.globinch.com/enterprise-java/security/pkix-path-building-failed-validation-sun-security-validatorexception/#Valid-Certification-Path-to-Requested-Target .
Copiando el texto del enlace, en caso de que este enlace muera:
Todo lo que necesita hacer para solucionar este error es agregar el certificado del servidor a su almacén clave de claves de confianza. Primero, debe descargar el documento del servidor.
Una vez que tenga el certificado en su disco duro, puede importarlo a la tienda de confianza de Java. Para importar el certificado al almacén clave de Java de confianza, puede usar la herramienta java ''keytool''. En el símbolo del sistema, vaya a la carpeta JRE bin, en mi caso, la ruta es: C: / Archivos de programa / Java / jdk1.7.0_75 / jre / bin. Luego use el comando keytool de la siguiente manera para importar el certificado a JRE.
keytool -import -alias _alias_name_ -keystore .. / lib / security / cacerts -file _path_to_cer_file
Le pedirá una contraseña. Por defecto, la contraseña es "changeit". Si la contraseña es diferente, es posible que no pueda importar el certificado.
Me he encontrado con esto varias veces y fue debido a una cadena de certificados incompleta. Si está utilizando el almacén de confianza java estándar, es posible que no tenga un certificado que sea necesario para completar la cadena de certificados que se requiere para validar el certificado del sitio SSL al que se está conectando.
Me encontré con este problema con algunos certificados de DigiCert y tuve que agregar manualmente el certificado intermediario.
Para mí, me encontré con este error al invocar una llamada al servicio web, me aseguro de que el sitio tenga un ssl válido, es decir, el logotipo en el costado de la url está marcado; de lo contrario, necesito agregar el certificado al almacén de claves de confianza en tu máquina
Solución Java 8: Acabo de tener este problema y lo resolví agregando el certificado del sitio remoto a mi almacén de claves Java. Mi solución se basó en la solución del blog myshittycode , que se basó en una solución anterior en el blog de mykong . Estas soluciones de artículos de blog se reducen a la descarga de un programa llamado InstallCert , que es una clase de Java que puede ejecutar desde la línea de comandos para obtener el certificado. A continuación, procede a instalar el certificado en el almacén de claves de Java.
El Readme InstallCert funcionó perfectamente para mí. Solo necesita ejecutar los siguientes comandos:
-
javac InstallCert.java
-
java InstallCert [host]:[port]
(Ingrese el número de lista dado del certificado que desea agregar en la lista cuando ejecute el comando - probablemente solo 1 ) -
keytool -exportcert -alias [host]-1 -keystore jssecacerts -storepass changeit -file [host].cer
-
sudo keytool -importcert -alias [host] -keystore [path to system keystore] -storepass changeit -file [host].cer
Vea el archivo README referenciado para un ejemplo si es necesario.
También me enfrenté a este tipo de problema. Estoy usando el servidor Tomcat luego puse carpeta endosada en tomcat luego está comenzando a funcionar. Y también reemplacé JDK1.6 con 1.7 entonces también funciona. Finalmente aprendí SSL luego resolví este tipo de problemas Primero, debe descargar los certificados de ese servidor de proveedor de servicios. Entonces, usted apretó la mano con éxito. 1.Intenta poner carpeta endosada en tu servidor De la siguiente manera 2.utiliza jdk1.7
Siguiente 3.Tratar de descargar certificados válidos usando SSL