java develops https to request ssl untrusted problem resolution

  • 2020-12-26 05:44:11
  • OfStack

This article focuses on the development of java https request ssl untrusted solution, specific analysis and implementation code is as follows.

The following error may be reported when requesting an https link in java code

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

The reason is that there is no certificate. It is possible to use url directly in the browser, as the browser should have saved the corresponding.ES16en certificate before.

The solution is either to obtain a valid certificate from the target machine or to ignore the certificate trust issue.

1. Obtain the valid certificate of the target machine

1. Compile and install the certificate program javac ES26en. java (the code is as follows)


/* 
 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. 
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 
 *  - Redistributions of source code must retain the above copyright 
 *   notice, this list of conditions and the following disclaimer. 
 * 
 *  - Redistributions in binary form must reproduce the above copyright 
 *   notice, this list of conditions and the following disclaimer in the 
 *   documentation and/or other materials provided with the distribution. 
 * 
 *  - Neither the name of Sun Microsystems nor the names of its 
 *   contributors may be used to endorse or promote products derived 
 *   from this software without specific prior written permission. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */
/** 
 * http://blogs.sun.com/andreas/resource/InstallCert.java 
 * Use: 
 * java InstallCert hostname 
 * Example: 
 *% java InstallCert ecc.fedora.redhat.com 
 */
import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/** 
 * Class used to add the server's certificate to the KeyStore 
 * with your trusted certificates. 
 */
public class InstallCert {
	public static void main(String[] args) throws Exception {
		String host;
		int port;
		char[] passphrase;
		if ((args.length == 1) || (args.length == 2)) {
			String[] c = args[0].split(":");
			host = c[0];
			port = (c.length == 1) ? 443 : Integer.parseint(c[1]);
			String p = (args.length == 1) ? "changeit" : args[1];
			passphrase = p.toCharArray();
		} else {
			System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
			return;
		}
		File file = new File("jssecacerts");
		if (file.isFile() == false) {
			char SEP = File.separatorchar;
			File dir = new File(System.getProperty("java.home") + SEP 
			          + "lib" + SEP + "security");
			file = new File(dir, "jssecacerts");
			if (file.isFile() == false) {
				file = new File(dir, "cacerts");
			}
		}
		System.out.println("Loading KeyStore " + file + "...");
		InputStream in = new FileInputStream(file);
		KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
		ks.load(in, passphrase);
		in.close();
		SSLContext context = SSLContext.getInstance("TLS");
		TrustManagerFactory tmf = 
		        TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		tmf.init(ks);
		X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
		SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
		context.init(null, new TrustManager[]{
			tm
		}
		, null);
		SSLSocketFactory factory = context.getSocketFactory();
		System.out.println("Opening connection to " + host + ":" + port + "...");
		SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
		socket.setSoTimeout(10000);
		try {
			System.out.println("Starting SSL handshake...");
			socket.startHandshake();
			socket.close();
			System.out.println();
			System.out.println("No errors, certificate is already trusted");
		}
		catch (SSLException e) {
			System.out.println();
			e.printStackTrace(System.out);
		}
		X509Certificate[] chain = tm.chain;
		if (chain == null) {
			System.out.println("Could not obtain server certificate chain");
			return;
		}
		BufferedReader reader = 
		        new BufferedReader(new InputStreamReader(System.in));
		System.out.println();
		System.out.println("Server sent " + chain.length + " certificate(s):");
		System.out.println();
		MessageDigest sha1 = MessageDigest.getInstance("SHA1");
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		for (int i = 0; i < chain.length; i++) {
			X509Certificate cert = chain[i];
			System.out.println 
			          (" " + (i + 1) + " Subject " + cert.getSubjectDN());
			System.out.println("  Issuer " + cert.getIssuerDN());
			sha1.update(cert.getEncoded());
			System.out.println("  sha1  " + toHexString(sha1.digest()));
			md5.update(cert.getEncoded());
			System.out.println("  md5   " + toHexString(md5.digest()));
			System.out.println();
		}
		System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
		String line = reader.readLine().trim();
		int k;
		try {
			k = (line.length() == 0) ? 0 : Integer.parseint(line) - 1;
		}
		catch (NumberFormatException e) {
			System.out.println("KeyStore not changed");
			return;
		}
		X509Certificate cert = chain[k];
		String alias = host + "-" + (k + 1);
		ks.setCertificateEntry(alias, cert);
		OutputStream out = new FileOutputStream("jssecacerts");
		ks.store(out, passphrase);
		out.close();
		System.out.println();
		System.out.println(cert);
		System.out.println();
		System.out.println 
		        ("Added certificate to keystore 'jssecacerts' using alias '" 
		            + alias + "'");
	}
	private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
	private static String toHexString(byte[] bytes) {
		StringBuilder sb = new StringBuilder(bytes.length * 3);
		for (int b : bytes) {
			b &= 0xff;
			sb.append(HEXDIGITS[b >> 4]);
			sb.append(HEXDIGITS[b & 15]);
			sb.append(' ');
		}
		return sb.toString();
	}
	private static class SavingTrustManager implements X509TrustManager {
		private final X509TrustManager tm;
		private X509Certificate[] chain;
		SavingTrustManager(X509TrustManager tm) {
			this.tm = tm;
		}
		public X509Certificate[] getAcceptedIssuers() {
			throw new UnsupportedOperationException();
		}
		public void checkClientTrusted(X509Certificate[] chain, String authType) 
		        throws CertificateException {
			throw new UnsupportedOperationException();
		}
		public void checkServerTrusted(X509Certificate[] chain, String authType) 
		        throws CertificateException {
			this.chain = chain;
			tm.checkServerTrusted(chain, authType);
		}
	}
}

2. Run the installation certificate program to generate the certificate

java InstallCert my.hoolai.com

Such as: java InstalCert smtp.zhangsan.com:465 admin
Without the port numbers for password and host, the port number given by default in the certificate acquisition program above is: 443 and the password is :changeit

3. According to the running prompt, enter 1, press enter, and generate a certificate named jssecacerts in the current directory

Place the certificate to $JAVA_HOME/jre/lib/security directory, be sure to keep in mind the JDK jre is used in the engineering environment!!!!!!

Or:

System.setProperty("javax.net.ssl.trustStore", "你的jssecacerts证书路径");

You can change the password and run the command from the security directory

keytool -storepasswd -new xxxcom -keystore cacerts

You can change the password and then use the command

keytool -list -v -keystore cacerts

When viewing the information of the file, it will prompt that the password is required for viewing. If the password entered matches the modified password, the modification is successful.

PS: At this point, ssl can be successfully used in this way. In addition, add 1, according to the just generated file jssecacerts, cer file can be generated.

The command is

keytool -export -alias xxx.com-1 -keystore jssecacerts -rfc -file xxx.cer

As mentioned, the default naming alias in the previous utility class was "-1". The password set using InstallCert needs to be sent to the password 1 in the cacerts file,

If you have changed the password, you need to change the corresponding password string in the InstallCert class, otherwise you will get the following exception:

java.security.UnrecoverableKeyException: Password verification failed

2. Ignore certificate trust issues

Source: http: / / mengyang. iteye. com/blog / 575671

1 Note that the method described in the article needs to be called before connection is created, like this:


trustAllHttpsCertificates();
HostnameVerifier hv = new HostnameVerifier() { 
    public boolean verify(String urlHostName, SSLSession session) { 
      return true; 
    } 
  };
HttpsURLConnection.setDefaultHostnameVerifier(hv);
connection = (HttpURLConnection) url.openConnection();

Well, both methods have worked.

conclusion

That is the end of this article on java's development of a solution to https's request for ssl's untrusted problem. I hope it will help you. Interested friends can continue to refer to other related topics in this site, if there is any deficiency, welcome to comment out. Thank you for your support!


Related articles: