(四)进行HTTPS请求并进行(或不进行)证书校验(示例)


原文:https://blog.csdn.net/justry_deng/article/details/81042379

 

 

 相关方法详情(非完美封装):

/**
 * 根据是否是https请求,获取HttpClient客户端
 *
 * TODO 本人这里没有进行完美封装。对于 校不校验校验证书的选择,本人这里是写死
 *      在代码里面的,你们在使用时,可以灵活二次封装。
 *
 * 提示: 此工具类的封装、相关客户端、服务端证书的生成,可参考我的这篇博客:
 *      <linked>https://blog.csdn.net/justry_deng/article/details/91569132</linked>
 *
 *
 * @param isHttps 是否是HTTPS请求
 *
 * @return  HttpClient实例
 * @date 2019/9/18 17:57
 */
private CloseableHttpClient getHttpClient(boolean isHttps) {
   CloseableHttpClient httpClient;
   if (isHttps) {
      SSLConnectionSocketFactory sslSocketFactory;
      try {
         /// 如果不作证书校验的话
         sslSocketFactory = getSocketFactory(false, null, null);
 
         /// 如果需要证书检验的话
         // 证书
         //InputStream ca = this.getClass().getClassLoader().getResourceAsStream("client/ds.crt");
         // 证书的别名,即:key。 注:cAalias只需要保证唯一即可,不过推荐使用生成keystore时使用的别名。
         // String cAalias = System.currentTimeMillis() + "" + new SecureRandom().nextInt(1000);
         //sslSocketFactory = getSocketFactory(true, ca, cAalias);
      } catch (Exception e) {
         throw new RuntimeException(e);
      }
      httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslSocketFactory).build();
      return httpClient;
   }
   httpClient = HttpClientBuilder.create().build();
   return httpClient;
}
 
/**
 * HTTPS辅助方法, 为HTTPS请求 创建SSLSocketFactory实例、TrustManager实例
 *
 * @param needVerifyCa
 *         是否需要检验CA证书(即:是否需要检验服务器的身份)
 * @param caInputStream
 *         CA证书。(若不需要检验证书,那么此处传null即可)
 * @param cAalias
 *         别名。(若不需要检验证书,那么此处传null即可)
 *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。
 *
 * @return SSLConnectionSocketFactory实例
 * @throws NoSuchAlgorithmException
 *         异常信息
 * @throws CertificateException
 *         异常信息
 * @throws KeyStoreException
 *         异常信息
 * @throws IOException
 *         异常信息
 * @throws KeyManagementException
 *         异常信息
 * @date 2019/6/11 19:52
 */
private static SSLConnectionSocketFactory getSocketFactory(boolean needVerifyCa, InputStream caInputStream, String cAalias)
      throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
      IOException, KeyManagementException {
   X509TrustManager x509TrustManager;
   // https请求,需要校验证书
   if (needVerifyCa) {
      KeyStore keyStore = getKeyStore(caInputStream, cAalias);
      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      trustManagerFactory.init(keyStore);
      TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
      if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
         throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
      }
      x509TrustManager = (X509TrustManager) trustManagers[0];
      // 这里传TLS或SSL其实都可以的
      SSLContext sslContext = SSLContext.getInstance("TLS");
      sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
      return new SSLConnectionSocketFactory(sslContext);
   }
   // https请求,不作证书校验
   x509TrustManager = new X509TrustManager() {
      @Override
      public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
      }
 
      @Override
      public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
         // 不验证
      }
 
      @Override
      public X509Certificate[] getAcceptedIssuers() {
         return new X509Certificate[0];
      }
   };
   SSLContext sslContext = SSLContext.getInstance("TLS");
   sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
   return new SSLConnectionSocketFactory(sslContext);
}
 
/**
 * 获取(密钥及证书)仓库
 * 注:该仓库用于存放 密钥以及证书
 *
 * @param caInputStream
 *         CA证书(此证书应由要访问的服务端提供)
 * @param cAalias
 *         别名
 *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。
 * @return 密钥、证书 仓库
 * @throws KeyStoreException 异常信息
 * @throws CertificateException 异常信息
 * @throws IOException 异常信息
 * @throws NoSuchAlgorithmException 异常信息
 * @date 2019/6/11 18:48
 */
private static KeyStore getKeyStore(InputStream caInputStream, String cAalias)
      throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
   // 证书工厂
   CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
   // 秘钥仓库
   KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
   keyStore.load(null);
   keyStore.setCertificateEntry(cAalias, certificateFactory.generateCertificate(caInputStream));
   return keyStore;
}

  

/** * 根据是否是https请求,获取HttpClient客户端 * * TODO 本人这里没有进行完美封装。对于 校不校验校验证书的选择,本人这里是写死 *      在代码里面的,你们在使用时,可以灵活二次封装。 * * 提示: 此工具类的封装、相关客户端、服务端证书的生成,可参考我的这篇博客: *      <linked>https://blog.csdn.net/justry_deng/article/details/91569132</linked> * * * @param isHttps 是否是HTTPS请求 * * @return  HttpClient实例 * @date 2019/9/18 17:57 */private CloseableHttpClient getHttpClient(boolean isHttps) {   CloseableHttpClient httpClient;   if (isHttps) {      SSLConnectionSocketFactory sslSocketFactory;      try {         /// 如果不作证书校验的话         sslSocketFactory = getSocketFactory(false, null, null);          /// 如果需要证书检验的话         // 证书         //InputStream ca = this.getClass().getClassLoader().getResourceAsStream("client/ds.crt");         // 证书的别名,即:key。 注:cAalias只需要保证唯一即可,不过推荐使用生成keystore时使用的别名。         // String cAalias = System.currentTimeMillis() + "" + new SecureRandom().nextInt(1000);         //sslSocketFactory = getSocketFactory(true, ca, cAalias);      } catch (Exception e) {         throw new RuntimeException(e);      }      httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslSocketFactory).build();      return httpClient;   }   httpClient = HttpClientBuilder.create().build();   return httpClient;} /** * HTTPS辅助方法, 为HTTPS请求 创建SSLSocketFactory实例、TrustManager实例 * * @param needVerifyCa *         是否需要检验CA证书(即:是否需要检验服务器的身份) * @param caInputStream *         CA证书。(若不需要检验证书,那么此处传null即可) * @param cAalias *         别名。(若不需要检验证书,那么此处传null即可) *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。 * * @return SSLConnectionSocketFactory实例 * @throws NoSuchAlgorithmException *         异常信息 * @throws CertificateException *         异常信息 * @throws KeyStoreException *         异常信息 * @throws IOException *         异常信息 * @throws KeyManagementException *         异常信息 * @date 2019/6/11 19:52 */private static SSLConnectionSocketFactory getSocketFactory(boolean needVerifyCa, InputStream caInputStream, String cAalias)      throws CertificateException, NoSuchAlgorithmException, KeyStoreException,      IOException, KeyManagementException {   X509TrustManager x509TrustManager;   // https请求,需要校验证书   if (needVerifyCa) {      KeyStore keyStore = getKeyStore(caInputStream, cAalias);      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());      trustManagerFactory.init(keyStore);      TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();      if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {         throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));      }      x509TrustManager = (X509TrustManager) trustManagers[0];      // 这里传TLS或SSL其实都可以的      SSLContext sslContext = SSLContext.getInstance("TLS");      sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());      return new SSLConnectionSocketFactory(sslContext);   }   // https请求,不作证书校验   x509TrustManager = new X509TrustManager() {      @Override      public void checkClientTrusted(X509Certificate[] arg0, String arg1) {      }       @Override      public void checkServerTrusted(X509Certificate[] arg0, String arg1) {         // 不验证      }       @Override      public X509Certificate[] getAcceptedIssuers() {         return new X509Certificate[0];      }   };   SSLContext sslContext = SSLContext.getInstance("TLS");   sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());   return new SSLConnectionSocketFactory(sslContext);} /** * 获取(密钥及证书)仓库 * 注:该仓库用于存放 密钥以及证书 * * @param caInputStream *         CA证书(此证书应由要访问的服务端提供) * @param cAalias *         别名 *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。 * @return 密钥、证书 仓库 * @throws KeyStoreException 异常信息 * @throws CertificateException 异常信息 * @throws IOException 异常信息 * @throws NoSuchAlgorithmException 异常信息 * @date 2019/6/11 18:48 */private static KeyStore getKeyStore(InputStream caInputStream, String cAalias)      throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {   // 证书工厂   CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");   // 秘钥仓库   KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());   keyStore.load(null);   keyStore.setCertificateEntry(cAalias, certificateFactory.generateCertificate(caInputStream));   return keyStore;}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM