(四)進行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