Ryan Elkins
Ryan Elkins

Reputation: 5797

Ignore certificate errors when requesting a URL in Java

I'm trying to print a URL (without having a browser involved at all) but the URL is currently throwing the following:

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

I'm calling the URL using a JEditorPane's setPage method, which just takes a URL as a parameter. Assuming I can't change anything server side and I still need to get to this resource, how would I go about ignoring the certificate error (or something else that gets me to my goal)?

Accessing this URL via a browser tells me the site is untrusted and asks me if I want to proceed.

Upvotes: 2

Views: 23064

Answers (5)

Chad
Chad

Reputation: 1

On a related note: my mutual certifcate authentication with a WCF .net Web Service was causing issues in my test environment. I added these two lines to my code to fix the problem and allow me to work through the issue:

//Uncomment this in case server demands some unsafe operations       
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");       

//this command allowed me to see the detailed debugger log for detecting the
//issue with my certs.
System.setProperty("javax.net.debug","all");

Here is a nice reference for dealing with SSL negotiation and certifcates in a Java/Windows/Unix world: Transport Layer Security (TLS) Renegotiation Issue Readme

Upvotes: 0

Nick H
Nick H

Reputation: 11535

If it is the same server that you will be contacting each time, it might be okay to simply trust this one certificate by adding it to the trust store. I wouldn't add this to the default cacerts file, but you can make your own keystore and specify it through the javax.net.ssl.trustStore system property.

Lastly, if you want to disable PKIX checking completely (which you should only do if you understand that this will compromise security quite a lot) the only way is to implement your own SSL context and trust manager as erickson has suggested.

Upvotes: 0

systempuntoout
systempuntoout

Reputation: 74104

I would use erickson solution.
Another way is to add server's certificate (probably self signed) to your trusted certificates KeyStore (I would do it just in your test enviroment).
Use:

java InstallCert YourHost

to create a jssecacerts file then copy it to the following folder:

$JAVA_HOME/jre/lib/security 

Upvotes: 2

erickson
erickson

Reputation: 269697

Extend JEditorPane to override the getStream() method.

Inside that method, you can open a URLConnection. Test whether it is an HttpsURLConnection. If it is, initialize your own SSLContext with a custom X509TrustManager that doesn't perform any checks. Get the context's SSLSocketFactory and set it as the socket factory for the connection. Then return the InputStream from the connection.

This will defeat any attempts by the runtime to protect the user from a spoof site serving up malware. If that's really what you want…

Upvotes: 10

ring bearer
ring bearer

Reputation: 20783

This is possibly because your certificate in your keystore for accessing target HTTPS URL does not match the certificate from server.

You need to import the certificate in to your JVM's keystore. Obtain keystore certificatesto access this URL and then importit into the main keystore with

keytool -importkeystore -srckeystore /path/to/custom/keystore -destkeystore $JAVA_HOME/jre/lib/security/cacerts

Assuming you are using Java from $JAVA_HOME

Upvotes: 3

Related Questions