Menu

 

Thoughts on Software Engineering

Disable Certificate Validation in Java SSL Connections

By design when we open an SSL connection in Java (e.g. through java.net.URL.openConnection(“https://….”)) the JSSE implementation of the SSL protocol performs few validations to ensure the requested host is not fake. This involves validation of the server’s X.509 certificate with the PKIX algorithm and checking the host name agains the certificate subject. If the SSL certificate is not validates as trusted or does not match the target host, an HTTPS and other SSL encrypted connection cannot be established and all attempts will result in SSLHandshakeException or IOException.

Example of HTTPS Connection in Java that will Fail Due to Certificate Validation Failure

Consider we are trying to download a resource from HTTPS server:

URL url = new URL("https://www.nakov.com:2083/");
URLConnection con = url.openConnection();
Reader reader = new InputStreamReader(con.getInputStream());
while (true) {
	int ch = reader.read();
	if (ch==-1) {
		break;
	}
	System.out.print((char)ch);
}

If the server uses self-signed X.509 certificate, we will get SSLHandshakeException the following exception during the SSL handshaking:

Exception in thread "main" 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(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	...

This exception can be avoided if we import the server’s self-signed certificate in the JVM trusted store, a file called “cacerts”. For more information see this post: http://www.java-samples.com/showtutorial.php?tutorialid=210.

We could have also another issue. If the server uses trusted certificate (issued from trusted CA like VeriSign), but for different host, we will get another exception (IOException) during the host verification step of the SSL handshaking:

Exception in thread "main" <strong>java.io.IOException: HTTPS hostname wrong: should be <www.nakov.com></strong>
	at sun.net.www.protocol.https.HttpsClient.checkURLSpoofing(Unknown Source)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)

How to Turn Off Certificate Validation in Java HTTPS Connections?

Avoiding these exceptions is possible by switching off the certificate validation and host verification for SSL for the current Java virtual machine. This can be done by replacing the default SSL trust manager and the default SSL hostname verifier:

import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class Example {
	public static void main(String[] args) throws Exception {
		// 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);

		URL url = new URL("https://www.nakov.com:2083/");
		URLConnection con = url.openConnection();
		Reader reader = new InputStreamReader(con.getInputStream());
		while (true) {
			int ch = reader.read();
			if (ch==-1) {
				break;
			}
			System.out.print((char)ch);
		}
	}
}

Voilla! Now the code runs as expected: it downloads the resource from an https address with invalid certificate.

Be careful when using this hack! Skipping certificate validation is dangerous and should be done in testing environments only.

Previews (39,155), Views (32,470), Comments (55)

55 Responses to “Disable Certificate Validation in Java SSL Connections”

  1. Amer says:

    Can this code be used in j2me?

    Thanks

  2. nakov says:

    I don’t know. You could test it in Java ME environment, of course.

  3. kaz says:

    Is this supposed to work when running the client from the command line? I have implemented this but I am still receiving the same error. You have any idea what may be happening?

  4. nakov says:

    I have no idea. It worked at the time it was written. Now we have newer Java versions that could possibly work differently.

  5. kaz says:

    It works … I found the issue I was having … it was in an old script that was being used to run the client. 😉 it was setting the command line parameter: -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol … which apparently did not recognize my hostname verifier. Thx for the response.

    JFYI … all that is needed when using JAX-WS is:

    HttpsURLConnection.setDefaultHostnameVerifier( new HostnameVerifier() {
    public boolean verify(String urlHostName, SSLSession session) {
    log.debug( “Warning: URL Host: ” + urlHostName + ” vs. ” + session.getPeerHost() );
    return true;
    }
    } );

  6. […] to a HTTPS server from Java and ignore the validity of the security certificate as well as Disable Certificate Validation in Java SSL Connections, but the accepted answer to the first is for HttpClient 4.0 (unfortunately I cannot upgrade, unless […]

  7. Madhu says:

    This is very helpful, it worked perfectly. The one change I did was making these two calls on the connection instance (instead of static calls)

    httpsConnection.setSSLSocketFactory(sc.getSocketFactory());
    httpsConnection.setHostnameVerifier(allHostsValid);

  8. […] I actually disabled the HTTPS certificate check by using the method described in this nifty blog: http://www.nakov.com/blog/2009/07/16/disable-certificate-validation-in-java-ssl-connections/. In actual production use, however, HTTPS URLs are handled by using the actual certificates […]

  9. Sweet – just what I needed – thank you. Only thing I needed to add was a permission in my java.policy file like so:
    permission javax.net.ssl.SSLPermission “setHostnameVerifier”;

  10. Federico says:

    Thank you very much!!!! very usefull!

  11. Prafulla says:

    it works, thanks much

  12. Prafulla says:

    it works, great help!!

  13. Daniel says:

    Very great, thank you!

  14. jeff says:

    Thanks. Very helpful — I was using a similar but incomplete solution that worked in some cases but not all. Not sure why it sometimes worked but anyhow, this is great!

  15. Pharmd57 says:

    Hello! fddgegf interesting fddgegf site! I’m really like it! Very, very fddgegf good!

  16. Shashank says:

    Thanks…
    Very Helpful

  17. me says:

    Can anybody help me why am I getting the following error ?
    Exception in thread “main” java.io.IOException: Server returned HTTP response code: 401 for URL: https://www.nakov.com:2083/
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1615)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
    at MainProject.Cert.main(Cert.java:58)

    • nakov says:

      This URL requires authentication (username + password). It says “401 Access Denied” and this is its correct behavior. HTTP code 401 is returned when the server needs authentication. You could try accessing another URL, e.g. https://appharbor.com/.

  18. me says:

    @nakov: the example you provided: https://appharbor.com/. has a valid certificate. So, Java can deal with it without the need to use the code. Can you provide me with another example for expired or self-signed certificate if you have any ?

  19. Raj says:

    Excellent post. Vey nice!!

  20. I was very happy to seek out this internet-site.I needed to thanks for your time for this glorious learn!! I positively enjoying each little little bit of it and I have you bookmarked to take a look at new stuff you weblog post. ralph lauren polo http://cheap-ralph-lauren-polos.webs.com/

  21. Russell Grokett says:

    Just a note if you use HTTPS Mutual SSL Authentication, this can cause a “sslv3 alert bad certificate” error.
    javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    as it nulls the SSL certs needed for the two-way handshake.
    Its fine to use this code if you do not use Mutual SSL Auth.

  22. Abhishek says:

    how do I pass username and password to the htpps connection.
    I am trying this but its not working

    byte[] encodedPassword = ( userName + “:” + password ).getBytes();
    BASE64Encoder encoder = new BASE64Encoder();
    con.setRequestProperty( “Authorization”,
    “Basic ” + encoder.encode( encodedPassword ) );

  23. Anonymous says:

    Thanks, it worked!

  24. Peter Altankov says:

    Thanks Svetlin, works like a charm!

  25. vutty says:

    Thanks. it is working.

  26. Steve says:

    How does one programmatically undo this change and get back to the original SSL security settings?

  27. Stefan says:

    Thank you very much Nakov. It´s very useful information!

  28. Ashis says:

    Thanks a lot. solved my issue

  29. Ehis says:

    Thanks a lot. It helped.

  30. getting error

    java.lang.UnsupportedClassVersionError: Bad version number in .class file

  31. Emilse says:

    Great!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Thanks!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  32. Miguel says:

    thanks very much!! Your code was very useful for me!!

  33. Anonymous says:

    thank you

  34. Bernardo says:

    You saved my life!!!! I have been trying to work my way around this problems for days…
    It works like a charm for me…
    If you ever come down to Mexico, we will have a beer (or two)

  35. Wasenshi says:

    You saved my life too!!
    If you ever come to Thailand in Asia we will have a beer(or two)

  36. Umair says:

    It worked for me.
    Thank You Very Much!!!

  37. Magesh says:

    Simply super…I got it:)

  38. スーパーコピーブランド格安販売店はこちらへ!品々の激安価格に持ったスーパーコピーブランド 代引きの新作はお客様に提供されます。安心、迅速、確実、お客様の手元にお届け致します。★弊社は9年の豊富な経験と実績を持っております。★一流の素材を選択し、精巧な作り方でまるで本物のようなな製品を造ります。★品質を重視、納期も厳守、お客様第一主義を貫きは当社の方針です。★驚きの低価格で商品をお客様に提供致します!★早速に購入へようこそ! http://www.wtobrand.com/sbom2.html

  39. ルイヴィトン 財布真心込めて最高 レベルのスーパーコピールイヴィトン偽物ブランド品をお届けしています。安全税関対策+ 素早い配送+随時の在庫補給+丁寧な対応+スーパーコピー販売業界最低価格に挑戦 !当店は業界最高品質に挑戦!全商品はプロの目にも分からないルイヴィトン 財布スーパーコピーです。 http://www.gginza.com/%E6%99%82%E8%A8%88/%E3%83%AD%E3%83%AC%E3%83%83%E3%82%AF%E3%82%B9/daytona/65198499868fb2b5.html

  40. 有効な対応を今回の世界的な金融と経済危機、スイス各界の去年は行動して。政府は前後して2度経済振興計画を発表し、税収の手段を通じて呼びかけと励まし社会の各分野の減少リストラ;経済界を積極的に対応し、勤務時間短くコスト削減の方式で、努力して就業市場の安定を維持する。昨年12月、スイス300社以上の企業のスタッフの労働時間短縮、今年1月にこのような企業が増えた1200家。スーパーコピーバッグ労働時間の短縮と同時に、大多数の企業が従業員を育成して、未来への就職市場は不測の風雲。最近の一項の経済調査によると、これまでの半分以上の従業員を保留スイスたい仕事で減少の給与、しかもしっかり職場の変化の準備。 http://www.bagkakaku.com/vuitton_wallet/wallet/148.html

  41. ルイヴィトン スーパーコピー「バッグ色は手触りがいいが、触ってみると、週囲の姉妹はこの綺麗、最近ずっと忙しくて、長い時間がかかりました、いい感じ ヴィトン スーパーコピー ルイヴィトンキーケース コピー当店ルイヴィトン 偽物は創業9年以上の老舗です。業界の長い歴史から言えばまだまだですが、創業 9 年以上の実績と信頼のあるお店です。全世界通信販売は6年前から行っております。さらに1年間で約数万件の販売実績があります。ルイヴィトン スーパーコピー 販売専門ショップです!ルイヴィトン コピー ブランドバッグ、財布、アクセサリー、手帳、ベルト、靴、腕時計、ネクタイ、スカーフなどを揃っております、日本国内最高級のルイヴィトン偽物ブランド激安販売! http://www.ooowatch.com/tokei/chopard

  42. 2010年7月8日、スイス布拉苏糸村――スイスタブ業の伝統的な休日で、多芸多才の音楽巨擘クインシージョーンズ(Quincyジョーンズ)オーデマピゲ表グループCEOの莫菲利(フィリップ・Merk)さんの案内でオーデマピゲタブ工場を見学しました。ウブロスーパーコピーこのオーデマピゲ表と縁の深い伝奇音楽人、この度の旅行の経験を発掘したオーデマピゲ表表壇の先駆けとしての深遠なタブの文化、特に見た自分の名前のMILLENARYミレニアムクインシージョーンズ(Quincyジョーンズ)限定腕時計の制作蘊奥。「オーデマピゲ工場、タブ職人たちに見せる好プレー印象が殘って。彼らは偉大な創造者、激情あふれるアーティスト、ちょうど私が音楽プロデューサーとしてサービスのあれらの才能豊かな人。」クインシージョーンズ(Quincyジョーンズ)は音楽史の上で影響力の裕福な伝説の人物は依然としてを提唱し、ポップスの普及発展に力を入れる。元トランペットのクインシージョーンズ、後に従事し、指揮、続々とアレンジ音楽レコード制作などの仕事。カルティエ時計コピープロデューサーの間で出版された数十枚ジャズミュージシャンのアルバムを務めるレコード、フランク・辛納屈(Frank Sinatra)、バーバラ・史翠珊(Barbara Streisand)、汤尼•クラスナイト(Tony Bennett)などの国際スターのプロデューサー。1978年、クインシージョーンズとマイケル・ジャクソン(MichaelJackson)と出会い、彼のために制作した『塀の外」や「戦慄」、「速い」など3枚のアルバムにレコード。こちらの達人生花の天才編曲家と慧眼識英雄の音楽伯楽は、常にその鋭い嗅覚の音楽を生み出し空前絶後の経典金曲。ファンの愛称をQのクインシージョーンズも気前情熱の化身。クインシージョーンズ人道的精神に基づいて救済、かつて人気歌手アメリカ召集46位を行いの「Weアレthe World四海一家》専輯レコードは美しい。オメガコピー彼は一人で創設のクインシージョーンズ基金会は保護児童権益を守るために努力することを目的とし、全世界の子どもの福祉、健康と尊厳。オーデマピゲ時計工場とこちらは平凡な音楽巨擘協力推進するQ計画。この計画を訴えの政界と社会大衆配慮靑少年の創作表現現し、必要の賛助と協力し、彼らの潜在力を発揮する。 http://www.bagkakaku.com/vuitton_bag/2/N51211.html

  43. Shashika says:

    This is very useful. Thank you!

  44. Alex Zaharow says:

    Big thanks! You bring the light for many years!

  45. Sunset Dreamer says:

    great article and tutorial through the steps

RSS feed for comments on this post. TrackBack URL

LEAVE A COMMENT