java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > JAVA自动下载SSL证书并导入到本地

JAVA如何自动下载SSL证书并导入到本地

作者:假大叔

这篇文章主要介绍了JAVA如何自动下载SSL证书并导入到本地问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

前言

基于https的访问很多情况下是需要证书认证。

解决办法不外乎几个。

第一种

可以用下面这行代码

以下这行代码是全局性的,表示当前程序所有请求都不会验证SSL的可靠性,慎用。

另外使用OKHTTP的话,在构建的时候,对SSLSocketFactoryHostnameVerifier设置相同的属性即可。

// 全局关闭SSL认证
DisableSSLCertificateCheckUtil.disableChecks();

工具类 DisableSSLCertificateCheckUtil.java

package com.ygsoft.hzc.tool;
import javax.net.ssl.*;
import java.io.IOException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public final class DisableSSLCertificateCheckUtil {
    /**
     * Prevent instantiation of utility class.
     */
    private DisableSSLCertificateCheckUtil() {
    }
    /**
     * Disable trust checks for SSL connections.
     */
    public static void disableChecks() {
        try {
            new URL("https://0.0.0.0/").getContent();
        } catch (IOException e) {
            // This invocation will always fail, but it will register the
            // default SSL provider to the URL class.
        }
        try {
            SSLContext sslc;
            sslc = SSLContext.getInstance("TLS");
            TrustManager[] trustManagerArray = {new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            }};
            sslc.init(null, trustManagerArray, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String s, SSLSession sslSession) {
                    return true;
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalArgumentException("证书校验异常!");
        }
    }
}

第二种

在这里我贴出一个自己写的证书导入工具类,复制粘贴即可用。

默认是443端口,根据需要可自己修改ssl的端口

逻辑

发起请求之前先检查证书是否已经存在硬盘并导入到系统,如果没有,那么主动下载并导入到系统。

代码片段

URL urlnormal = new URL(fullUrl);
//加载证书
if(urlnormal.getProtocol().equals("https")){
	String sslpath = FileUtil.getCertPath()+urlnormal.getHost().replaceAll("[.]", "");
	//如果不存在ssl证书,那么创建导入一个证书
	if(!new File(sslpath).exists()){
		SSLCertUtil.importCert(urlnormal.getHost(), null);
	}
	System.setProperty("javax.net.ssl.trustStore", sslpath);				
}
// 发情HTTP 请求
......
.....

工具类 SSLCertUtil .java

package com.hzc.tool;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
/**
 * 自动导入证书.
 * @author huangzongcheng
 * 2017.06.13
 */
public class SSLCertUtil {  
	private static final String TAG = SSLCertUtil.class.getSimpleName();
	public static void main(String[] args) {
		try {
			importCert("www.kuaidi100.com",null);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 淇濆瓨瀵煎叆SSL璇佷功
	 * @param url
	 * @param pwd
	 * @throws Exception
	 */
    public static void importCert(String url,String pwd) throws Exception {  
    	LogUtil.d(TAG, "http url format = xxx.com[:port] ");
    	LogUtil.d(TAG, String.format("getting %s info",url));
    	//瑙f瀽鍦板潃锛屽垎绂荤鍙�
	    String[] urlformat = url.split(":");  
        String host = urlformat[0];  
        int port = (urlformat.length == 1) ? 443 : Integer.parseInt(urlformat[1]);  
        String p = StringUtil.isEmpty(pwd) ? "changeit" : pwd;  
        char[] passphrase = p.toCharArray();  
        String certName = host.replaceAll("[.]", "");
	    File file = new File(certName);  
	    if (file.isFile() == false) {  
	        char SEP = File.separatorChar;  
	        File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security");  
	        file = new File(dir, certName);  
	        if (file.isFile() == false) {  
	        	file = new File(dir, "cacerts");  
	        }  
	    }  
	    LogUtil.d(TAG,String.format("loading keystore %s", 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();  
	    LogUtil.d(TAG,String.format("opening connection to %s:%d", host,port));
	    SSLSocket socket = (SSLSocket)factory.createSocket(host, port);  
	    socket.setSoTimeout(10000);  
	    try {  
	        LogUtil.d(TAG,"Starting SSL handshake");
	        socket.startHandshake();  
	        socket.close();  
	        LogUtil.d(TAG,"No errors, certificate is already trusted");  
	    } catch (SSLException e) {  
	        System.out.println();  
	        e.printStackTrace(System.out);  
	    }  
	    X509Certificate[] chain = tm.chain;  
	    if (chain == null) {  
	        LogUtil.d(TAG,"Could not obtain server certificate chain");  
	        return;  
	    }  
	    LogUtil.d(TAG,"Server sent " + chain.length + " certificate(s):");
	    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();  
	    }  
	    int k = 0; 
	    X509Certificate cert = chain[k];  
	    String alias = host.replaceAll("[.]", "");  
	    ks.setCertificateEntry(alias, cert);  
	    OutputStream out = new FileOutputStream(FileUtil.getCertPath()+certName);  
	    ks.store(out, passphrase);  
	    out.close();  
	    System.out.println(cert);  
	    System.out.println("Added certificate to keystore "+certName+" 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);  
	    }  
    }  
}  

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文