中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java實現自動安裝校驗TLS/SSL證書

發布時間:2020-10-26 17:29:56 來源:億速云 閱讀:387 作者:Leah 欄目:開發技術

Java實現自動安裝校驗TLS/SSL證書?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

主要實現如下功能:

1.自動檢測,校驗根證書,校驗過期時間,校驗簽名的證書是否有效,校驗證書和域名是否匹配

2.實現證書的自動存儲,自動安裝,加載

3.實現普通Socket自動升級為SSLSocket

一.實現配置類

首先,我們先添加2個配置類

package com.ssl.rx.http;

import java.security.KeyStore;

public class ConnectionConfiguration {

	/** 證書文件路徑 */
private String truststorePath;
	/** 證書類型 */
private String truststoreType;
	/** 證書文件密碼 */
private String truststorePassword;
	/** 是否驗證證書鏈的簽名有效性 */
private boolean verifyChainEnabled = true;
	/** 是否校驗根證書,注意,自簽名證書沒有根證書 */
private boolean verifyRootCAEnabled = true;
	/** 是否允許通過自簽名證書 */
private boolean selfSignedCertificateEnabled = false;
	/** 是否檢查證書的有效期 */
private boolean expiredCertificatesCheckEnabled = true;
	/** 檢查域名的匹配情況 */
private boolean notMatchingDomainCheckEnabled = true;

	private String server;
	private int port;

	public ConnectionConfiguration() {
		truststorePassword = "WlZSak5GcFVUbTlsVjJSNg==";
		truststorePath = "socket_tls_clientTrust.cert";
		truststoreType = "jks";
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public String getServer() {
		return server;
	}

	public void setServer(String server) {
		this.server = server;
	}

	public boolean isExpiredCertificatesCheckEnabled() {
		return expiredCertificatesCheckEnabled;
	}

	public void setSelfSignedCertificateEnabled(boolean selfSignedCertificateEnabled) {
		this.selfSignedCertificateEnabled = selfSignedCertificateEnabled;
	}

	public void setExpiredCertificatesCheckEnabled(boolean expiredCertificatesCheckEnabled) {
		this.expiredCertificatesCheckEnabled = expiredCertificatesCheckEnabled;
	}

	public boolean isSelfSignedCertificateEnabled() {
		return selfSignedCertificateEnabled;
	}

	public boolean isNotMatchingDomainCheckEnabled() {
		return notMatchingDomainCheckEnabled;
	}

	public boolean isVerifyRootCAEnabled() {
		return verifyRootCAEnabled;
	}

	public void setVerifyRootCAEnabled(boolean verifyRootCAEnabled) {
		this.verifyRootCAEnabled = verifyRootCAEnabled;
	}

	public void setVerifyChainEnabled(boolean verifyChainEnabled) {
		this.verifyChainEnabled = verifyChainEnabled;
	}

	public boolean isVerifyChainEnabled() {

		return verifyChainEnabled;
	}

	public String getTruststoreType() {
		return truststoreType;
	}

	public void setTruststoreType(String truststoreType) {
		this.truststoreType = truststoreType;
	}

	public String getTruststorePassword() {
		return truststorePassword;
	}

	public void setTruststorePassword(String truststorePassword) {
		this.truststorePassword = truststorePassword;
	}

	public String getTruststorePath() {
		return truststorePath;
	}

	public void setTruststorePath(String truststorePath) {
		this.truststorePath = truststorePath;
	}

	public void setNotMatchingDomainCheckEnabled(boolean notMatchingDomainCheckEnabled) {
		this.notMatchingDomainCheckEnabled = notMatchingDomainCheckEnabled;
	}

}


然后增加一個用于存儲keystore的javaBean

package com.ssl.rx.http;

public class KeyStoreOptions {
	private final String type;
	private final String path;
	private final String password;

	public KeyStoreOptions(String type, String path, String password) {
		super();
		this.type = type;
		this.path = path;
		this.password = password;
	}

	public String getType() {
		return type;
	}

	public String getPath() {
		return path;
	}

	public String getPassword() {
		return password;
	}

	@Override
public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((password == null) ? 0 : password.hashCode());
		result = prime * result + ((path == null) ? 0 : path.hashCode());
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		return result;
	}

	@Override
public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		KeyStoreOptions other = (KeyStoreOptions) obj;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (path == null) {
			if (other.path != null)
				return false;
		} else if (!path.equals(other.path))
			return false;
		if (type == null) {
			if (other.type != null)
				return false;
		} else if (!type.equals(other.type))
			return false;
		return true;
	}
}

最后,我們來實現核心部分,證書管理器

二.實現核心代碼

package com.ssl.rx.http;


public class SSLX509CertificateManager {

	private static final Logger logger = Logger.getLogger("SSLX509CertificateManager");
	private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
	private static Pattern cnPattern = Pattern.compile("(?i)(cn=)([^,]*)");
	private static Map<KeyStoreOptions, KeyStore> stores = new HashMap<KeyStoreOptions, KeyStore>();

	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();
	}

	

	/**
	 * 開始握手等一系列密鑰協商
	 * 
	 * @param socket
	 * @return
	 */
public static boolean startHandshake(SSLSocket socket) {
		try {
			logger.log(Level.INFO, "-開始握手,認證服務器證書-");
			socket.startHandshake();
			System.out.println();
			logger.log(Level.INFO, "-握手結束,結束認證服務器證書-");
		} catch (SSLException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static SSLSocket createTrustCASocket(String host, int port, ConnectionConfiguration config)
throws Exception {
		if (config == null) {
			config = new ConnectionConfiguration();
		}
		KeyStore ks = getKeyStore(config);
		SSLContext context = SSLContext.getInstance("TLS");
		TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		tmf.init(ks);
		X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
		CAX509TrustManager tm = new CAX509TrustManager(defaultTrustManager, ks, config);

		context.init(null, new TrustManager[] { tm }, new SecureRandom());
		SSLSocketFactory factory = context.getSocketFactory();

		logger.log(Level.INFO, "開始連接: " + host + ":" + port + "...");
		SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
		socket.setSoTimeout(10000);

		config.setServer(host);
		config.setPort(port);
		// config.setTrustKeyStore(ks);
		X509Certificate certificate = (X509Certificate) ks.getCertificate(host + ":" + port);

		if (certificate != null && isValid(certificate)) {
			logger.log(Level.INFO, "-證書文件存在并且有效,無需進行握手-");
			return socket;
		}
		if (!startHandshake(socket)) {
			logger.log(Level.SEVERE, "-握手失敗-");
			return null;
		}
		X509Certificate[] chain = tm.chain;
		if (chain == null || chain.length == 0) {
			logger.log(Level.SEVERE, "-證書鏈為空,認證失敗-");
			return null;
		}

		if (config.isVerifyRootCAEnabled()) {
			boolean isValidRootCA = checkX509CertificateRootCA(ks, chain, config.isSelfSignedCertificateEnabled());
			if (!isValidRootCA) {
				return null;
			}
		}

		return socket;
	}

	/**
	 * 獲取keystore,防治多次加載
	 * 
	 * @param config
	 * @return
	 * @throws KeyStoreException
	 * @throws IOException
	 * @throws NoSuchAlgorithmException
	 * @throws CertificateException
	 * @throws FileNotFoundException
	 */
private static KeyStore getKeyStore(ConnectionConfiguration config) throws KeyStoreException, IOException,
			NoSuchAlgorithmException, CertificateException, FileNotFoundException {
		KeyStore ks;
		synchronized (stores) {
			KeyStoreOptions options = new KeyStoreOptions(config.getTruststoreType(), config.getTruststorePath(),
					config.getTruststorePassword());
			if (stores.containsKey(options)) {
				logger.log(Level.INFO, "從緩存中獲取trustKeystore");
				ks = stores.get(options);

			} else {
				File file = new File(config.getTruststorePath());
				char[] password = config.getTruststorePassword().toCharArray();

				logger.log(Level.INFO, "加載" + file + "證書文件");
				ks = KeyStore.getInstance(KeyStore.getDefaultType());
				if (!file.exists()) {
					logger.log(Level.INFO, "證書文件不存在,選擇自動創建");
					ks.load(null, password);
				} else {
					logger.log(Level.INFO, "證書文件存在,開始加載");
					InputStream in = new FileInputStream(file);
					ks.load(in, password);
					in.close();
				}
				stores.put(options, ks);
			}

		}
		return ks;
	}

	public static SSLSocket createTrustCASocket(String host, int port) throws Exception {

		return createTrustCASocket(host, port, null);
	}

	public static SSLSocket createTrustCASocket(Socket s, ConnectionConfiguration config) throws Exception {
		if (config == null) {
			config = new ConnectionConfiguration();
		}

		KeyStore ks = getKeyStore(config);
		SSLContext context = SSLContext.getInstance("TLS");
		TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		tmf.init(ks);
		X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
		CAX509TrustManager tm = new CAX509TrustManager(defaultTrustManager, ks, config);

		context.init(null, new TrustManager[] { tm }, new SecureRandom());
		SSLSocketFactory factory = context.getSocketFactory();

		String host = s.getInetAddress().getHostName();
		int port = s.getPort();
		logger.log(Level.INFO, "開始連接: " + host + ":" + port + "...");

		SSLSocket socket = (SSLSocket) factory.createSocket(s, host, port, true);
		socket.setSoTimeout(10000);

		config.setServer(s.getInetAddress().getHostName());
		config.setPort(s.getPort());

		X509Certificate certificate = (X509Certificate) ks.getCertificate(host + ":" + s.getPort());
		if (certificate != null && isValid(certificate)) {
			logger.log(Level.INFO, "-證書文件存在并且有效,無需進行握手-");
			return socket;
		}
		if (!startHandshake(socket)) {
			return null;
		}
		X509Certificate[] chain = tm.chain;
		if (chain == null || chain.length == 0) {
			logger.log(Level.SEVERE, "-證書鏈為空,認證失敗-");
			return null;
		}
		if (config.isVerifyRootCAEnabled()) {
			boolean isValidRootCA = checkX509CertificateRootCA(ks, chain, config.isSelfSignedCertificateEnabled());
			if (!isValidRootCA) {
				logger.log(Level.SEVERE, "根證書校驗無效");
				return null;
			}
		}
		return socket;

	}

	public static SSLSocket createTrustCASocket(Socket s) throws Exception {

		return createTrustCASocket(s, null);
	}

	public static class CAX509TrustManager implements X509TrustManager {

		private final X509TrustManager tm;
		private X509Certificate[] chain;
		private KeyStore keyStore;
		private ConnectionConfiguration config;
		public MessageDigest sha1 = null;
		public MessageDigest md5 = null;

		public CAX509TrustManager(X509TrustManager tm, KeyStore ks, ConnectionConfiguration config)
throws NoSuchAlgorithmException {
			this.tm = tm;
			this.keyStore = ks;
			sha1 = MessageDigest.getInstance("SHA1");
			md5 = MessageDigest.getInstance("MD5");
			this.config = config;
		}

		public X509Certificate[] getAcceptedIssuers() {
			return tm.getAcceptedIssuers(); // 生成證書數組,用于存儲新證書
		}

		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
			tm.checkClientTrusted(chain, authType); // 檢查客戶端
		}

		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
			if (this.chain == null) {
				this.chain = getAcceptedIssuers();
			}
			if (chain != null && chain.length > 0) {
				if (!checkX509CertificateValid(chain, config)) {
					logger.log(Level.SEVERE, "證書校驗未通過");
					return;
				}
				for (int i = 0; i < chain.length; i++) {
					X509Certificate certificate = chain[i];
					if (i == 0) {
						saveCAToKeyStore(certificate, config.getServer() + ":" + config.getPort());
					} else {
						saveCAToKeyStore(certificate, null);
					}
				}
			}
		}

		public void saveCAToKeyStore(X509Certificate certificate, String aliasKey) throws CertificateEncodingException {
			try {
				X509Certificate cert = certificate;
				System.out.println(" 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()));

				String alias = keyStore.getCertificateAlias(cert);
				if (alias == null || alias != null && !isValid(certificate)) {
					if (aliasKey == null || aliasKey.length() == 0) {
						alias = cert.getSubjectDN().getName();
					} else {
						alias = aliasKey;
						logger.log(Level.INFO, "設定指定證書別名:" + alias);
					}
					keyStore.setCertificateEntry(alias, certificate);
					OutputStream out = new FileOutputStream(config.getTruststorePath());
					keyStore.store(out, config.getTruststorePassword().toCharArray());
					out.close();
					chain = Arrays.copyOf(chain, chain.length + 1);
					chain[chain.length - 1] = certificate;
					logger.fine(certificate.toString());
				}

			} catch (KeyStoreException e) {
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (CertificateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	public static boolean isValid(X509Certificate cert) {
		if (cert == null) {
			return false;
		}
		try {
			cert.checkValidity();
		} catch (CertificateExpiredException e) {
			e.printStackTrace();
			return false;
		} catch (CertificateNotYetValidException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 校驗證書的有效性
	 * 
	 * @param chain
	 * @param config
	 * @return
	 */
private static boolean checkX509CertificateValid(X509Certificate[] chain, ConnectionConfiguration config) {
		boolean result = true;
		if (config.isExpiredCertificatesCheckEnabled()) {
			result = result && checkX509CertificateExpired(chain);
		}

		if (config.isVerifyChainEnabled()) {
			result = result && checkX509CertificateChain(chain);
		}

		if (config.isNotMatchingDomainCheckEnabled()) {
			result = result && checkIsMatchDomain(chain, config.getServer());
		}

		return result;

	}

	/**
	 * 檢查是否匹配域名
	 * 
	 * @param x509Certificates
	 * @param server
	 * @return
	 */
public static boolean checkIsMatchDomain(X509Certificate[] x509Certificates, String server) {
		server = server.toLowerCase();
		List<String> peerIdentities = getPeerIdentity(x509Certificates[0]);
		if (peerIdentities.size() == 1 && peerIdentities.get(0).startsWith("*.")) {
			String peerIdentity = peerIdentities.get(0).replace("*.", "");
			if (!server.endsWith(peerIdentity)) {
				return false;
			}
		} else {
			for (int i = 0; i < peerIdentities.size(); i++) {
				String peerIdentity = peerIdentities.get(i).replace("*.", "");
				if (server.endsWith(peerIdentity)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 校驗根證書
	 * 
	 * @param trustStore
	 * @param x509Certificates
	 * @param isSelfSignedCertificate
	 *      是否自簽名證書
	 * @return
	 */
public static boolean checkX509CertificateRootCA(KeyStore trustStore, X509Certificate[] x509Certificates,
			boolean isSelfSignedCertificate) {
		List<String> peerIdentities = getPeerIdentity(x509Certificates[0]);
		boolean trusted = false;
		try {
			int size = x509Certificates.length;
			trusted = trustStore.getCertificateAlias(x509Certificates[size - 1]) != null;
			if (!trusted && size == 1 && isSelfSignedCertificate) {
				logger.log(Level.WARNING, "-強制認可自簽名證書-");
				trusted = true;
			}
		} catch (KeyStoreException e) {
			e.printStackTrace();
		}
		if (!trusted) {
			logger.log(Level.SEVERE, "-根證書簽名的網站:" + peerIdentities + "不能被信任");
		}

		return trusted;
	}

	/**
	 * 檢查證書是否過期
	 * 
	 * @param x509Certificates
	 * @return
	 */
public static boolean checkX509CertificateExpired(X509Certificate[] x509Certificates) {
		Date date = new Date();
		for (int i = 0; i < x509Certificates.length; i++) {
			try {
				x509Certificates[i].checkValidity(date);
			} catch (GeneralSecurityException generalsecurityexception) {
				logger.log(Level.SEVERE, "-證書已經過期-");
				return false;
			}
		}
		return true;
	}

	/**
	 * 校驗證書鏈的完整性
	 * 
	 * @param x509Certificates
	 * @return
	 */
public static boolean checkX509CertificateChain(X509Certificate[] x509Certificates) {
		Principal principalLast = null;
		List<String> peerIdentities = getPeerIdentity(x509Certificates[0]);

		for (int i = x509Certificates.length - 1; i >= 0; i--) {
			X509Certificate x509certificate = x509Certificates[i];
			Principal principalIssuer = x509certificate.getIssuerDN();
			Principal principalSubject = x509certificate.getSubjectDN();
			if (principalLast != null) {
				if (principalIssuer.equals(principalLast)) {
					try {
						PublicKey publickey = x509Certificates[i + 1].getPublicKey();
						x509Certificates[i].verify(publickey);
					} catch (GeneralSecurityException generalsecurityexception) {

						logger.log(Level.SEVERE, "-無效的證書簽名-" + peerIdentities);
						return false;
					}
				} else {
					logger.log(Level.SEVERE, "-無效的證書簽名-" + peerIdentities);
					return false;
				}
			}
			principalLast = principalSubject;
		}

		return true;
	}

	/**
	 * 返回所有可用的簽名方式 鍵值對 如CN=VeriSignMPKI-2-6
	 * 
	 * @param certificate
	 * @return
	 */
private static List<String> getSubjectAlternativeNames(X509Certificate certificate) {
		List<String> identities = new ArrayList<String>();
		try {
			Collection<List<&#63;>> altNames = certificate.getSubjectAlternativeNames();
			if (altNames == null) {
				return Collections.emptyList();
			}

			Iterator<List<&#63;>> iterator = altNames.iterator();
			do {
				if (!iterator.hasNext())
					break;
				List<&#63;> altName = iterator.next();
				int size = altName.size();
				if (size >= 2) {
					identities.add((String) altName.get(1));
				}

			} while (true);
		} catch (CertificateParsingException e) {
			e.printStackTrace();
		}
		return identities;
	}

	/**
	 * 返回所有可用的簽名方式的值
	 * 
	 * @param certificate
	 * @return
	 */
public static List<String> getPeerIdentity(X509Certificate x509Certificate) {
		List<String> names = getSubjectAlternativeNames(x509Certificate);
		if (names.isEmpty()) {
			String name = x509Certificate.getSubjectDN().getName();
			Matcher matcher = cnPattern.matcher(name);
			if (matcher.find()) {
				name = matcher.group(2);
			}
			names = new ArrayList<String>();
			names.add(name);
		}
		return names;
	}
}

三.測試代碼

public class TestX509CertManager {

 public static void main(String[] args) {
		try {
			SSLSocket baiduSocket = SSLX509CertificateManager.createTrustCASocket("www.baidu.com", 443);
			SSLSocket taobaoSocket = SSLX509CertificateManager.createTrustCASocket("www.taobao.com", 443);
			SSLSocket imququSocket = SSLX509CertificateManager.createTrustCASocket("imququ.com", 443);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

四.附加測試代碼

我們這里附加一個工具類,專門來實現Server-Side與Client-Side的SSLSocket 連接,也可以用于測試我們的上述代碼,只不過需要稍加改造。

package com.tianwt.rx.http;

public class SSLTrustManager implements javax.net.ssl.TrustManager,
      javax.net.ssl.X509TrustManager ,HostnameVerifier {
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
      return new X509Certificate[]{};
    }
 
    public boolean isServerTrusted(
        java.security.cert.X509Certificate[] certs) {
      return true;
    }
 
    public boolean isClientTrusted(
        java.security.cert.X509Certificate[] certs) {
      return true;
    }
 
    public void checkServerTrusted(
        java.security.cert.X509Certificate[] certs, String authType)
        throws java.security.cert.CertificateException {
      return;
    }
 
    public void checkClientTrusted(
        java.security.cert.X509Certificate[] certs, String authType)
        throws java.security.cert.CertificateException {
      return;
    }
     
      @Override
    public boolean verify(String urlHostName, SSLSession session) { //允許所有主機
      return true;
    }
    
  /**
  * 客戶端使用
  */
  public static HttpURLConnection connectTrustAllServer(String strUrl) throws Exception {
     
    return connectTrustAllServer(strUrl,null);
  }
  /**
  * 客戶端使用
  * 
  * @param strUrl 要訪問的地址
  * @param proxy 需要經過的代理
  * @return
  * @throws Exception
  */
  public static HttpURLConnection connectTrustAllServer(String strUrl,Proxy proxy) throws Exception {
     
     javax.net.ssl.TrustManager[] trustCertsmanager = new javax.net.ssl.TrustManager[1];
     javax.net.ssl.TrustManager tm = new SSLTrustManager();
     trustCertsmanager[0] = tm;
     javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
         .getInstance("TLS");
     sc.init(null, trustCertsmanager, null);
     javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
         .getSocketFactory());
     
     HttpsURLConnection.setDefaultHostnameVerifier((HostnameVerifier) tm);
     
    URL url = new URL(strUrl);
    HttpURLConnection urlConn = null;
    if(proxy==null)
    {
    	 urlConn = (HttpURLConnection) url.openConnection();
    }else{
    	 urlConn = (HttpURLConnection) url.openConnection(proxy);
    }
    urlConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36");
    return urlConn;
  }

  /**
  * 用于雙向認證,客戶端使用
  * 
  * @param strUrl
  * @param proxy
  * @return
  * @throws KeyStoreException
  * @throws NoSuchAlgorithmException
  * @throws CertificateException
  * @throws FileNotFoundException
  * @throws IOException
  * @throws UnrecoverableKeyException
  * @throws KeyManagementException
  */
  public static HttpURLConnection connectProxyTrustCA(String strUrl,Proxy proxy) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException
  {
	  HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
			
			@Override
public boolean verify(String s, SSLSession sslsession) {
				
				return true;
			}
		});
	  String clientKeyStoreFile = "D:/JDK8Home/tianwt/sslClientKeys"; 
    String clientKeyStorePwd = "123456"; 
    String catServerKeyPwd = "123456"; 
    
    String serverTrustKeyStoreFile = "D:/JDK8Home/tianwt/sslClientTrust"; 
    String serverTrustKeyStorePwd = "123456"; 
    KeyStore serverKeyStore = KeyStore.getInstance("JKS"); 
    serverKeyStore.load(new FileInputStream(clientKeyStoreFile), clientKeyStorePwd.toCharArray()); 
 
    KeyStore serverTrustKeyStore = KeyStore.getInstance("JKS"); 
    serverTrustKeyStore.load(new FileInputStream(serverTrustKeyStoreFile), serverTrustKeyStorePwd.toCharArray()); 
 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    kmf.init(serverKeyStore, catServerKeyPwd.toCharArray()); 
 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    tmf.init(serverTrustKeyStore); 
 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 
    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); 
    
    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
		
	  URL url = new URL(strUrl);
	  HttpURLConnection httpURLConnection = null;
	  if(proxy==null)
	  {
		  httpURLConnection = (HttpURLConnection) url.openConnection();
	  }else{
		  httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
	  }
	  httpURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36");
	  return httpURLConnection;

  }
  /**
  * 用于單向認證,客戶端使用
  * 
  * server側只需要自己的keystore文件,不需要truststore文件
	* client側不需要自己的keystore文件,只需要truststore文件(其中包含server的公鑰)。
  * 此外server側需要在創建SSLServerSocket之后設定不需要客戶端證書:setNeedClientAuth(false)
  * @param strUrl
  * @param proxy
  * @return
  * @throws KeyStoreException
  * @throws NoSuchAlgorithmException
  * @throws CertificateException
  * @throws FileNotFoundException
  * @throws IOException
  * @throws UnrecoverableKeyException
  * @throws KeyManagementException
  */
  public static HttpURLConnection connectProxyTrustCA2(String strUrl,Proxy proxy) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException
  {
	  HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
			
			@Override
public boolean verify(String s, SSLSession sslsession) {
				
				return true;
			}
		});
    
    String serverTrustKeyStoreFile = "D:/JDK8Home/tianwt/sslClientTrust"; 
    String serverTrustKeyStorePwd = "123456"; 
 
    KeyStore serverTrustKeyStore = KeyStore.getInstance("JKS"); 
    serverTrustKeyStore.load(new FileInputStream(serverTrustKeyStoreFile), serverTrustKeyStorePwd.toCharArray()); 
 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    tmf.init(serverTrustKeyStore); 
 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 
    sslContext.init(null, tmf.getTrustManagers(), null); 
    
    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
		
	  URL url = new URL(strUrl);
	  HttpURLConnection httpURLConnection = null;
	  if(proxy==null)
	  {
		  httpURLConnection = (HttpURLConnection) url.openConnection();
	  }else{
		  httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
	  }
	  httpURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36");
	  return httpURLConnection;

  }
  /**
  * 用于雙向認證
  * @param socketClient 是否產生socket
  * @return
  * @throws KeyStoreException
  * @throws NoSuchAlgorithmException
  * @throws CertificateException
  * @throws FileNotFoundException
  * @throws IOException
  * @throws UnrecoverableKeyException
  * @throws KeyManagementException
  */
  public SSLSocket createTlsConnect(Socket socketClient) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException
	{
		
		  String protocol = "TLS"; 
	    String serverKey = "D:/JDK8Home/tianwt/sslServerKeys"; 
	    String serverTrust = "D:/JDK8Home/tianwt/sslServerTrust"; 
	    String serverKeyPwd = "123456"; //私鑰密碼
	    String serverTrustPwd = "123456"; //信任證書密碼
	    String serverKeyStorePwd = "123456"; // keystore存儲密碼
	     
	    KeyStore keyStore = KeyStore.getInstance("JKS");  
	    keyStore.load(new FileInputStream(serverKey),serverKeyPwd.toCharArray()); 
	    
	    KeyStore tks = KeyStore.getInstance("JKS");
	    tks.load(new FileInputStream(serverTrust), serverTrustPwd.toCharArray());
	    
	    KeyManagerFactory km = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  
	    km.init(keyStore, serverKeyStorePwd.toCharArray());
	    
	    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
	    tmf.init(tks);
	    
	    SSLContext sslContext = SSLContext.getInstance(protocol); 
	    sslContext.init(km.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); //第一項是用來做服務器驗證的
	    
	    SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
	    SSLSocket clientSSLSocket = (SSLSocket) sslSocketFactory.createSocket(socketClient,socketClient.getInetAddress().getHostAddress(),socketClient.getPort(), true);
	    clientSSLSocket.setNeedClientAuth(false);
	    clientSSLSocket.setUseClientMode(false);
	    
	    return clientSSLSocket;
	}
  /**
  * 用于單向認證
  * server側只需要自己的keystore文件,不需要truststore文件
	* client側不需要自己的keystore文件,只需要truststore文件(其中包含server的公鑰)。
  * 此外server側需要在創建SSLServerSocket之后設定不需要客戶端證書:setNeedClientAuth(false)
  * @param socketClient
  * @return
  * @throws KeyStoreException
  * @throws NoSuchAlgorithmException
  * @throws CertificateException
  * @throws FileNotFoundException
  * @throws IOException
  * @throws UnrecoverableKeyException
  * @throws KeyManagementException
  */
  public static SSLSocket createTlsConnect2(Socket socketClient) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException
 	{
 		
 		  String protocol = "TLS"; 
 	    String serverKey = "D:/JDK8Home/tianwt/sslServerKeys"; 
 	    String serverKeyPwd = "123456"; //私鑰密碼
 	    String serverKeyStorePwd = "123456"; // keystore存儲密碼
 	     
 	    KeyStore keyStore = KeyStore.getInstance("JKS");  
 	    keyStore.load(new FileInputStream(serverKey),serverKeyPwd.toCharArray()); 
 	    
 	    KeyManagerFactory km = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  
 	    km.init(keyStore, serverKeyStorePwd.toCharArray());
 	    
 	    SSLContext sslContext = SSLContext.getInstance(protocol); 
 	    sslContext.init(km.getKeyManagers(), null, new SecureRandom()); //第一項是用來做服務器驗證的
 	    
 	    SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
 	    SSLSocket clientSSLSocket = (SSLSocket) sslSocketFactory.createSocket(socketClient,socketClient.getInetAddress().getHostAddress(),socketClient.getPort(), true);
 	    clientSSLSocket.setNeedClientAuth(false);
 	    clientSSLSocket.setUseClientMode(false);
 	    
 	    return clientSSLSocket;
 	}
  
  /**
  * 將普通的socket轉為sslsocket,客戶端和服務端均可使用
  * 
  * 服務端使用的時候是把普通的socket轉為sslsocket,并且作為服務器套接字(注意:指的不是ServerSocket,當然ServerSocket的本質也是普通socket)
  * 
  * @param remoteHost
  * @param isClient
  * @return
  */
public static SSLSocket getTlsTrustAllSocket(Socket remoteHost,boolean isClient)
{
		SSLSocket remoteSSLSocket = null;
		SSLContext context = SSLTrustManager.getTrustAllSSLContext(isClient);
		try {
			remoteSSLSocket = (SSLSocket) context.getSocketFactory().createSocket(remoteHost, remoteHost.getInetAddress().getHostName(),remoteHost.getPort(), true);
			remoteSSLSocket.setTcpNoDelay(true);
			remoteSSLSocket.setSoTimeout(5000);
			remoteSSLSocket.setNeedClientAuth(false); //這里設置為true時會強制握手
			remoteSSLSocket.setUseClientMode(isClient); //注意服務器和客戶的角色選擇 
			 
		} catch (IOException e) {
			e.printStackTrace();
		}
		return remoteSSLSocket;
	}
	/**
	 * 用于客戶端,通過所有證書驗證
	 * @param isClient 是否生成客戶端SSLContext,否則生成服務端SSLContext
	 * @return
	 */
  public static SSLContext getTrustAllSSLContext(boolean isClient)
  {
	  String protocol = "TLS"; 
	  javax.net.ssl.SSLContext sc = null;
	  try {
		javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
		  javax.net.ssl.TrustManager tm = new SSLTrustManager();
		  trustAllCerts[0] = tm;
		  sc = javax.net.ssl.SSLContext
		      .getInstance(protocol);
		  
		  if(isClient)
		  {
		  	sc.init(null, trustAllCerts, null); //作為客戶端使用
		  }
		  else
		  {
	 	    String serverKeyPath = "D:/JDK8Home/tianwt/sslServerKeys"; 
	 	    String serverKeyPwd = "123456"; //私鑰密碼
	 	    String serverKeyStorePwd = "123456"; // keystore存儲密碼
	 	    
	 	    KeyStore keyStore = KeyStore.getInstance("JKS");  
	 	    keyStore.load(new FileInputStream(serverKeyPath),serverKeyPwd.toCharArray()); 
	 	    
		  	KeyManagerFactory km = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  
		 	  km.init(keyStore, serverKeyStorePwd.toCharArray());
		 	  KeyManager[] keyManagers = km.getKeyManagers();
		 	  keyManagers = Arrays.copyOf(keyManagers, keyManagers.length+1);
	 	    sc.init(keyManagers, null, new SecureRandom());
		  }
	} catch (KeyManagementException e) {
		e.printStackTrace();
	} catch (NoSuchAlgorithmException e) {
		e.printStackTrace();
	} catch (UnrecoverableKeyException e) {
		e.printStackTrace();
	} catch (KeyStoreException e) {
		e.printStackTrace();
	} catch (CertificateException e) {
		e.printStackTrace();
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	  return sc;
  }
 }

看完上述內容,你們掌握Java實現自動安裝校驗TLS/SSL證書的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临海市| 宜黄县| 海安县| 丁青县| 伊金霍洛旗| 庄浪县| 瑞昌市| 出国| 资源县| 铁力市| 大理市| 扎兰屯市| 蓝田县| 余姚市| 甘孜县| 黄陵县| 施秉县| 武山县| 宜兰市| 广宗县| 宜川县| 博罗县| 莱芜市| 聂拉木县| 肇庆市| 广元市| 台州市| 兴隆县| 正宁县| 德庆县| 前郭尔| 绥江县| 牙克石市| 通渭县| 扎鲁特旗| 克拉玛依市| 内江市| 买车| 伊金霍洛旗| 玉屏| 宁海县|