Java code to show case how java client deals with https certificates

Visit a valid https site to see if there will be anything wrong

	public static void tryAuthorizedHttps() throws Exception {

		URL url = new URL("https://www.baidu.com/");
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
		InputStream in = conn.getInputStream();
		String page = IOUtils.toString(in, "utf8");
		System.out.println(page); // successfully printed
		System.out.println("===================");
		

		//get the first X509 cert on the certificate chain
		X509Certificate x5Cert = (X509Certificate) conn.getServerCertificates()[0];
		System.out.println("Subject:" + x5Cert.getSubjectDN()); // CN = *.baidu.com
		System.out.println("Issuer:" + x5Cert.getIssuerDN());  // CN = VeriSign

		in.close();
	}

It works because JDK has contained mainstream CA authorities, including VeriSign. You can verify it by

cat $JAVA_HOME/jre/lib/security/cacerts|grep -a VeriSign

Visit a https site with a self-signed certificate to see if there will be anything wrong

	public static void trySelfSignedHttps() throws Exception {

		URL url = new URL("https://some.self.signed.cert.com");
		URLConnection conn = url.openConnection();
		InputStream in = conn.getInputStream(); // javax.net.ssl.SSLHandshakeException:
												// unable to find valid certification path to requested target
		String page = IOUtils.toString(in, "utf8");
		System.out.println(page);

		in.close();

	}

You will encounter an SSL related exception since the certificate is self-signed.

P.S. If the site’s certificate is issued by an unknown CA, the same Exception will be thrown with a different exception message.

Add the self-signed certificate on client side and visit the site again

Let the owner of some.self.signed.cert.com pass you their self-signed certificate file. Assume it is named as “cjx_cert.pem”.

Then you can avoid exceptions and still stay in security.

	public static void trySelfSignedHttpsWithTrustManager() throws Exception {
		CertificateFactory cf = CertificateFactory.getInstance("X.509");
		InputStream certInput = StX509Main.class.getResourceAsStream("/examples/x509/cjx_cert.pem");
		Certificate cjxCert;
		try {
		    cjxCert = cf.generateCertificate(certInput);
		    System.out.println("cjxCert=" + ((X509Certificate) cjxCert).getSubjectDN());
		} finally {
			IOUtils.closeQuietly(certInput);		   
		}

		// Create a KeyStore containing the cert
		String keyStoreType = KeyStore.getDefaultType();
		KeyStore trustedKeyStore = KeyStore.getInstance(keyStoreType);
		trustedKeyStore.load(null, null);
		trustedKeyStore.setCertificateEntry("cjxCert", cjxCert);

		// Create a TrustManager that trusts the cert in our KeyStore
		String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
		TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
		tmf.init(trustedKeyStore);

		// Create an SSLContext that uses our TrustManager
		SSLContext context = SSLContext.getInstance("TLS");
		context.init(null, tmf.getTrustManagers(), null);

		// Tell the URLConnection to use a SocketFactory from our SSLContext
		URL url = new URL("https://some.self.signed.cert.com");
		HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
		conn.setSSLSocketFactory(context.getSocketFactory());
		InputStream in = conn.getInputStream();  
		String page = IOUtils.toString(in, "utf8");
		System.out.println(page);

		in.close();

	}

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.