项目遇到的实际需求: java从信任所有证书到对server证书进行校验
最近项目上开发了一个rest api
,放在了一台linux
服务器上,并且启用了https
连接;在另一台服务器上写了一个功能需要去调用linux
机器上的api
。
项目里面自己封装了一个HttpsClient
的类,用来发送https
请求,并且在里面重写了TrustManager
,方法体都为空,这样就不会对server
的证书以及client
的证书进行校验,能够顺利的从另一台服务器调用linux
上的api
。
/*** * A default TrustManager which will trust any certificate.**/
private static class DefaultTrustManager implements X509TrustManager {@Overridepublic void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return null;}
}
但是上面的这种方法是不安全的,对server
的证书以没有进行校验,就不能确定和自己进行通信的server
,到底是不是真正的那个我想要通信的server
,有可能是一个中间的,黑客部署的server
,这样就会导致数据的安全问题。
于是需要在另一台这端对linux server
端的证书进行认证,确认server
是不是真正想要的server
。
解决方案:
在linux
服务器上,使用openssl
生成了一个自签名的ssl
证书(如何生成ssl证书),用这个证书来启用linux server
的https
证书,并且将这个证书放到另一台的某个目录,然后另一台系统上的java
代码,在发送请求的时候,将证书放到keyStore
里面,这样java
就能对这个证书进行认证。
下面是ChatGPT
给出的示例代码: 读取指定的每一个路径上的证书,放到JKS
格式的keyStore
里面,然后用这个keyStore
初始化TrustManager
,最后用TrustManager
创建sslcontext
。
private SSLContext getSSLContext(JSONArray certificates, String protocol) throws Exception {SSLContext sc = null;if (certificates != null) {String certFileName = null;try {// Create a temp keystore object to be used to make the HTTPS callKeyStore keystore = KeyStore.getInstance("JKS");keystore.load(null,null);for (int i=0; i < certificates.size(); i++) {certFileName = (String)certificates.get(i);try (BufferedInputStream bis = FileFactory.newBufferedInputStream((String)certificates.get(i))) {CertificateFactory cf = CertificateFactory.getInstance("X.509");Certificate cert = cf.generateCertificate(bis);keystore.setCertificateEntry("cert" + i, cert);}}TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());tmf.init(keystore);// Create and initialize the SSL context that will be used by the HTTPS connectionsc = SSLContext.getInstance(protocol);sc.init(null, tmf.getTrustManagers(), null);} catch(IOException e) {throw e;} catch(CertificateException e) {throw e;} catch(KeyStoreException | NoSuchAlgorithmException | KeyManagementException e) {throw e;}}return sc;}
更多关于https
的文章,请参考我的https
专栏:https://blog.csdn.net/u011069294/category_11083017.html?spm=1001.2014.3001.5482