标签:x509 对象 factory 好的 net socket 常用 string public
https使用了很多年,而且人们对安全的渴望让https更加的普及,个人觉得https主要解决了2个主要的安全问题。
1. 通过数字证书保证通信数据发给正确的接收方。
2. 通过对称加密来保障通信过程中,数据不被窃听。
其实没有数字证书也是可以完成通信的,只是浏览器会提醒本次通信是不安全的,虽然通信过程中是不会被破解的,但是浏览器认为你请求的服务器不一定是真正的服务器而已
浏览器会提示不安全,但你仍然收到了展示的页面,所以说即使证书不正确,也是可以通信的。其实后台用HttpClient来请求https数据的时候,也会遇到此类困扰,此前常用的忽略证书,但这样虽然也能得到数据,从安全的角度来说是不可接受的,一些大公司里面的代码安全扫描工具很容易此类问题。
正确的做法是应该将你访问服务器的证书添加在你的java请求中,具体有以下2种方式
1. 将目标服务器的证书添加至HttpClient所用jdk证书文件
keytool -import -alias ${alias} -keystore ${JAVA_HOME}/jre/lib/security/cacerts -file ${path-to-certificate-file}
如果 keytool 要求你输入密码,在你没有变更过的情况下,该值默认为:changeit
参照下图导出证书,如命名为:baidu.cer
keytool -import -alias baidu -keystore ${JAVA_HOME}/jre/lib/security/cacerts -file baidu.cer
2. java代码动态加载目标网站的证书
方法一虽好,但对服务器入侵的太深,而且强依赖环境,甚至有些环境是不容许导入的,那么通过java代码动态加载证书便十分的可行
keytool -import -alias baidu -keystore java.baidu.cacert -file baidu.cer
java代码可参照如下(注意要将上面命令生成的证书文件java.baidu.cacert添加至你的项目里面):
import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.net.URL; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; public class LoadCert { public static void main(String[] args) throws Exception { // 加载 Keytool 生成的证书文件 String p = "changeit"; char[] passphrase = p.toCharArray(); InputStream in = LoadCert.class.getResourceAsStream("/java.baidu.cacert"); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(in, passphrase); in.close(); // 构造 javax.net.ssl.TrustManager 对象 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509", "SunJSSE"); tmf.init(ks); TrustManager[] tms = tmf.getTrustManagers(); // 使用构造好的 TrustManager 访问相应的 https 站点 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tms, new java.security.SecureRandom()); SSLSocketFactory ssf = sslContext.getSocketFactory(); URL myURL = new URL("https://replace.to.your.site.real.url/"); HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection(); httpsConn.setSSLSocketFactory(ssf); InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream()); int respInt = insr.read(); while (respInt != -1) { System.out.print((char) respInt); respInt = insr.read(); } } }
标签:x509 对象 factory 好的 net socket 常用 string public
原文地址:https://www.cnblogs.com/it-science/p/12846103.html