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

 更新时间:2023年07月29日 09:23:07   作者:假大叔  
这篇文章主要介绍了JAVA如何自动下载SSL证书并导入到本地问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

前言

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

解决办法不外乎几个。

  • 忽略SSL证书
  • 导入ssl证书

第一种

可以用下面这行代码

以下这行代码是全局性的,表示当前程序所有请求都不会验证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);  
	    }  
    }  
}  

总结

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

相关文章

  • Spring Security 过滤器注册脉络梳理

    Spring Security 过滤器注册脉络梳理

    这篇文章主要介绍了Spring Security过滤器注册脉络梳理,Spring Security在Servlet的过滤链中注册了一个过滤器FilterChainProxy,它会把请求代理到Spring Security自己维护的多个过滤链,每个过滤链会匹配一些URL,如果匹配则执行对应的过滤器
    2022-08-08
  • 背包问题-动态规划java实现的分析与代码

    背包问题-动态规划java实现的分析与代码

    这篇文章主要给大家介绍了关于背包问题动态规划java实现的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • mybatis的foreach标签语法报错的解决

    mybatis的foreach标签语法报错的解决

    这篇文章主要介绍了mybatis的foreach标签语法报错的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 基于solr全文检索实现原理(详谈)

    基于solr全文检索实现原理(详谈)

    下面小编就为大家分享一篇基于solr全文检索实现原理详谈,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • IntelliJ IDEA安装scala插件并创建scala工程的步骤详细教程

    IntelliJ IDEA安装scala插件并创建scala工程的步骤详细教程

    这篇文章主要介绍了IntelliJ IDEA安装scala插件并创建scala工程的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Java8 如何正确高效的使用并行流

    Java8 如何正确高效的使用并行流

    这篇文章主要介绍了Java8 如何正确高效的使用并行流,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java使用自定义注解实现函数测试功能示例

    Java使用自定义注解实现函数测试功能示例

    这篇文章主要介绍了Java使用自定义注解实现函数测试功能,结合实例形式分析了java自定义注解在函数测试过程中相关功能、原理与使用技巧,需要的朋友可以参考下
    2019-10-10
  • RocketMQ生产消息与消费消息超详细讲解

    RocketMQ生产消息与消费消息超详细讲解

    这篇文章主要介绍了RocketMQ生产消息与消费消息,RocketMQ可用于以三种方式发送消息:可靠的同步、可靠的异步和单向传输。前两种消息类型是可靠的,因为无论它们是否成功发送都有响应
    2022-12-12
  • JDK1.8使用的垃圾回收器和执行GC的时长以及GC的频率方式

    JDK1.8使用的垃圾回收器和执行GC的时长以及GC的频率方式

    这篇文章主要介绍了JDK1.8使用的垃圾回收器和执行GC的时长以及GC的频率方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • ThreadPoolExecutor线程池原理及其execute方法(详解)

    ThreadPoolExecutor线程池原理及其execute方法(详解)

    下面小编就为大家带来一篇ThreadPoolExecutor线程池原理及其execute方法(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06

最新评论