How to connect via HTTPS using Jsoup?
In my case, all I needed to do was to add the .validateTLSCertificates(false) in my connection
Document doc = Jsoup.connect(httpsURLAsString)
.timeout(60000).validateTLSCertificates(false).get();
I also had to increase the read timeout but I think this is irrelevant
I stumbled over the answers here and in the linked question in my search and want to add two pieces of information, as the accepted answer doesn't fit my quite similar scenario, but there is an additional solution that fits even in that case (cert and hostname don't match for test systems).
- There is a github request to add such a functionality. So perhaps soon the problem will be solved: https://github.com/jhy/jsoup/pull/343 edit: Github request was resolved and the method to disable certificate validation is: validateTLSCertificates(boolean validate)
- Based on http://www.nakov.com/blog/2009/07/16/disable-certificate-validation-in-java-ssl-connections/ I found a solution which seems to work (at least in my scenario where jsoup 1.7.3 is called as part of a maven task). I wrapped it in a method
disableSSLCertCheck()
that I call before the very first Jsoup.connect().
Before you use this method, you should be really sure that you understand what you do there - not checking SSL certificates is a really stupid thing. Always use correct SSL certificates for your servers which are signed by a commonly accepted CA. If you can't afford a commonly accepted CA use correct SSL certificates nevertheless with @BalusC accepted answer above. If you can't configure correct SSL certificates (which should never be the case in production environments) the following method could work:
private void disableSSLCertCheck() throws NoSuchAlgorithmException, KeyManagementException {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
If you want to do it the right way, and/or you need to deal with only one site, then you basically need to grab the SSL certificate of the website in question and import it in your Java key store. This will result in a JKS file which you in turn set as SSL trust store before using Jsoup (or java.net.URLConnection
).
You can grab the certificate from your webbrowser's store. Let's assume that you're using Firefox.
- Go to the website in question using Firefox, which is in your case https://web2.uconn.edu/driver/old/timepoints.php?stopid=10
- Left in the address bar you'll see "uconn.edu" in blue (this indicates a valid SSL certificate)
- Click on it for details and then click on the More information button.
- In the security dialogue which appears, click the View Certificate button.
- In the certificate panel which appears, go to the Details tab.
- Click the deepest item of the certificate hierarchy, which is in this case "web2.uconn.edu" and finally click the Export button.
Now you've a web2.uconn.edu.crt
file.
Next, open the command prompt and import it in the Java key store using the keytool
command (it's part of the JRE):
keytool -import -v -file /path/to/web2.uconn.edu.crt -keystore /path/to/web2.uconn.edu.jks -storepass drowssap
The -file
must point to the location of the .crt
file which you just downloaded. The -keystore
must point to the location of the generated .jks
file (which you in turn want to set as SSL trust store). The -storepass
is required, you can just enter whatever password you want as long as it's at least 6 characters.
Now, you've a web2.uconn.edu.jks
file. You can finally set it as SSL trust store before connecting as follows:
System.setProperty("javax.net.ssl.trustStore", "/path/to/web2.uconn.edu.jks");
Document document = Jsoup.connect("https://web2.uconn.edu/driver/old/timepoints.php?stopid=10").get();
// ...
As a completely different alternative, particularly when you need to deal with multiple sites (i.e. you're creating a world wide web crawler), then you can also instruct Jsoup (basically, java.net.URLConnection
) to blindly trust all SSL certificates. See also section "Dealing with untrusted or misconfigured HTTPS sites" at the very bottom of this answer: Using java.net.URLConnection to fire and handle HTTP requests