I am calling some HTTPS web service which the following Client:
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; } }
Test:
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); } }
I got the following output:
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
Do I need any certificate to be put at jdk/jre/lib/security??? Also, I have a xxx_IE.crt and xxx_FX.crt (for Firefox and IE respectively, and they don't work for the above Java client, so do I need a specific certificate for the Java client?
Thanks.
You need to set certificate to hit this url. use below code to set keystore:
System.setProperty("javax.net.ssl.trustStore","clientTrustStore.key"); System.setProperty("javax.net.ssl.trustStorePassword","qwerty");
Java 8 Solution: I just had this problem and solved it by adding the remote site's certificate to my Java keystore. My solution was based on the solution at the myshittycode blog, which was based on a previous solution in mykong's blog. These blog article solutions boil down to downloading a program called InstallCert, which is a Java class you can run from the command line to obtain the certificate. You then proceed to install the certificate in Java's keystore.
The InstallCert Readme worked perfectly for me. You just need to run the following commands:
javac InstallCert.java
java InstallCert [host]:[port]
(Enter the given list number of the certificate you want to add in the list when you run the command - likely just 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
See the referenced README file for an example if need be.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With