|
|
@@ -0,0 +1,209 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2018-2025. All rights reserved.
|
|
|
+ */
|
|
|
+
|
|
|
+package com.sooka.utils;
|
|
|
+
|
|
|
+import okhttp3.OkHttpClient;
|
|
|
+import org.apache.http.client.HttpClient;
|
|
|
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
|
|
+import org.apache.http.impl.client.CloseableHttpClient;
|
|
|
+import org.apache.http.impl.client.HttpClients;
|
|
|
+import org.bouncycastle.crypto.BlockCipher;
|
|
|
+import org.bouncycastle.crypto.engines.AESEngine;
|
|
|
+import org.bouncycastle.crypto.prng.SP800SecureRandomBuilder;
|
|
|
+import org.openeuler.BGMProvider;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import javax.net.ssl.*;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
+import java.net.URL;
|
|
|
+import java.security.*;
|
|
|
+import java.security.cert.X509Certificate;
|
|
|
+import java.util.Locale;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+public class SSLCipherSuiteUtil {
|
|
|
+ private static final Logger LOGGER = LoggerFactory.getLogger(SSLCipherSuiteUtil.class);
|
|
|
+ private static CloseableHttpClient httpClient;
|
|
|
+ private static OkHttpClient okHttpClient;
|
|
|
+
|
|
|
+ private static final int CIPHER_LEN = 256;
|
|
|
+
|
|
|
+ private static final int ENTROPY_BITS_REQUIRED = 384;
|
|
|
+
|
|
|
+ public static HttpClient createHttpClient(String protocol) throws Exception {
|
|
|
+ SSLContext sslContext = getSslContext(protocol);
|
|
|
+ // create factory
|
|
|
+ SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
|
|
|
+ new String[]{protocol}, Constant.SUPPORTED_CIPHER_SUITES, new TrustAllHostnameVerifier());
|
|
|
+
|
|
|
+ httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
|
|
|
+ return httpClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static HttpClient createHttpClientWithVerify(String protocol) throws Exception {
|
|
|
+ SSLContext sslContext = getSslContextWithVerify(protocol);
|
|
|
+ // create factory
|
|
|
+ SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
|
|
|
+ new String[]{protocol}, Constant.SUPPORTED_CIPHER_SUITES, new TheRealHostnameVerifier());
|
|
|
+
|
|
|
+ httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
|
|
|
+ return httpClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static OkHttpClient createOkHttpClient(String protocol) throws Exception {
|
|
|
+ SSLContext sslContext = getSslContext(protocol);
|
|
|
+ // Create an ssl socket factory with our all-trusting manager
|
|
|
+ SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
|
|
+ OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
|
|
+ .sslSocketFactory(sslSocketFactory, new TrustAllManager())
|
|
|
+ .hostnameVerifier(new TrustAllHostnameVerifier());
|
|
|
+ okHttpClient = builder.connectTimeout(10, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();
|
|
|
+ return okHttpClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static OkHttpClient createOkHttpClientWithVerify(String protocol) throws Exception {
|
|
|
+ SSLContext sslContext = getSslContextWithVerify(protocol);
|
|
|
+ SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
|
|
+
|
|
|
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(Constant.TRUST_MANAGER_FACTORY);
|
|
|
+ tmf.init((KeyStore) null);
|
|
|
+ TrustManager[] verify = tmf.getTrustManagers();
|
|
|
+ OkHttpClient.Builder builder = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory,
|
|
|
+ (X509TrustManager) verify[0]).hostnameVerifier(new TheRealHostnameVerifier());
|
|
|
+
|
|
|
+ okHttpClient = builder.connectTimeout(10, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();
|
|
|
+ return okHttpClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static HttpURLConnection createHttpsOrHttpURLConnection(URL uUrl, String protocol) throws Exception {
|
|
|
+ // initial connection
|
|
|
+ if (uUrl.getProtocol().toUpperCase(Locale.getDefault()).equals(Constant.HTTPS)) {
|
|
|
+ SSLContext sslContext = getSslContext(protocol);
|
|
|
+ HttpsURLConnection.setDefaultHostnameVerifier(new TrustAllHostnameVerifier());
|
|
|
+ HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
|
|
+ return (HttpsURLConnection) uUrl.openConnection();
|
|
|
+ }
|
|
|
+ return (HttpURLConnection) uUrl.openConnection();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static HttpURLConnection createHttpsOrHttpURLConnectionWithVerify(URL uUrl, String protocol) throws Exception {
|
|
|
+ // initial connection
|
|
|
+ if (uUrl.getProtocol().toUpperCase(Locale.getDefault()).equals(Constant.HTTPS)) {
|
|
|
+ SSLContext sslContext = getSslContextWithVerify(protocol);
|
|
|
+ HttpsURLConnection.setDefaultHostnameVerifier(new TheRealHostnameVerifier());
|
|
|
+ HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
|
|
+ return (HttpsURLConnection) uUrl.openConnection();
|
|
|
+ }
|
|
|
+ return (HttpURLConnection) uUrl.openConnection();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static SSLContext getSslContext(String protocol) throws UnsupportProtocolException,
|
|
|
+ NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
|
|
|
+ if (!Constant.GM_PROTOCOL.equals(protocol) && !Constant.INTERNATIONAL_PROTOCOL.equals(protocol)) {
|
|
|
+ LOGGER.info("Unsupport protocol: {}, Only support GMTLS TLSv1.2", protocol);
|
|
|
+ throw new UnsupportProtocolException("Unsupport protocol, Only support GMTLS TLSv1.2");
|
|
|
+ }
|
|
|
+ // Create a trust manager that does not validate certificate chains
|
|
|
+ TrustAllManager[] trust = {new TrustAllManager()};
|
|
|
+ KeyManager[] kms = null;
|
|
|
+ SSLContext sslContext;
|
|
|
+
|
|
|
+ sslContext = SSLContext.getInstance(Constant.INTERNATIONAL_PROTOCOL, "SunJSSE");
|
|
|
+
|
|
|
+ if (Constant.GM_PROTOCOL.equals(protocol)) {
|
|
|
+ Security.insertProviderAt(new BGMProvider(), 1);
|
|
|
+ sslContext = SSLContext.getInstance(Constant.GM_PROTOCOL, "BGMProvider");
|
|
|
+ }
|
|
|
+ SecureRandom secureRandom = getSecureRandom();
|
|
|
+ sslContext.init(kms, trust, secureRandom);
|
|
|
+ sslContext.getServerSessionContext().setSessionCacheSize(8192);
|
|
|
+ sslContext.getServerSessionContext().setSessionTimeout(3600);
|
|
|
+ return sslContext;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static SSLContext getSslContextWithVerify(String protocol)
|
|
|
+ throws UnsupportProtocolException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException,
|
|
|
+ KeyStoreException {
|
|
|
+ if (!Constant.GM_PROTOCOL.equals(protocol) && !Constant.INTERNATIONAL_PROTOCOL.equals(protocol)) {
|
|
|
+ LOGGER.info("Unsupport protocol: {}, Only support GMTLS TLSv1.2", protocol);
|
|
|
+ throw new UnsupportProtocolException("Unsupport protocol, Only support GMTLS TLSv1.2");
|
|
|
+ }
|
|
|
+ KeyManager[] kms = null;
|
|
|
+ SSLContext sslContext = SSLContext.getInstance(Constant.INTERNATIONAL_PROTOCOL, "SunJSSE");
|
|
|
+ SecureRandom secureRandom = getSecureRandom();
|
|
|
+
|
|
|
+ if (Constant.GM_PROTOCOL.equals(protocol)) {
|
|
|
+ Security.insertProviderAt(new BGMProvider(), 1);
|
|
|
+ sslContext = SSLContext.getInstance(Constant.GM_PROTOCOL, "BGMProvider");
|
|
|
+ }
|
|
|
+
|
|
|
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(Constant.TRUST_MANAGER_FACTORY);
|
|
|
+ tmf.init((KeyStore) null);
|
|
|
+ TrustManager[] verify = tmf.getTrustManagers();
|
|
|
+ sslContext.init(kms, verify, secureRandom);
|
|
|
+
|
|
|
+ sslContext.getServerSessionContext().setSessionCacheSize(8192);
|
|
|
+ sslContext.getServerSessionContext().setSessionTimeout(3600);
|
|
|
+ return sslContext;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 不校验域名
|
|
|
+ private static class TrustAllHostnameVerifier implements HostnameVerifier {
|
|
|
+ public boolean verify(String hostname, SSLSession session) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验域名
|
|
|
+ private static class TheRealHostnameVerifier implements HostnameVerifier {
|
|
|
+ public boolean verify(String hostname, SSLSession session) {
|
|
|
+ if (HostName.checkHostName(hostname)) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
|
|
|
+ return hv.verify(hostname, session);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 不校验服务端证书
|
|
|
+ private static class TrustAllManager implements X509TrustManager {
|
|
|
+ private X509Certificate[] issuers;
|
|
|
+
|
|
|
+ public TrustAllManager() {
|
|
|
+ this.issuers = new X509Certificate[0];
|
|
|
+ }
|
|
|
+
|
|
|
+ public X509Certificate[] getAcceptedIssuers() {
|
|
|
+ return issuers;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
|
|
+ }
|
|
|
+
|
|
|
+ public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static SecureRandom getSecureRandom() {
|
|
|
+ SecureRandom source;
|
|
|
+ try {
|
|
|
+ source = SecureRandom.getInstance(Constant.SECURE_RANDOM_ALGORITHM_NATIVE_PRNG_NON_BLOCKING);
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
+ try {
|
|
|
+ source = SecureRandom.getInstanceStrong();
|
|
|
+ } catch (NoSuchAlgorithmException ex) {
|
|
|
+ LOGGER.error("get SecureRandom failed", e);
|
|
|
+ throw new RuntimeException("get SecureRandom failed");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ boolean predictionResistant = true;
|
|
|
+ BlockCipher cipher = new AESEngine();
|
|
|
+ boolean reSeed = false;
|
|
|
+ return new SP800SecureRandomBuilder(source, predictionResistant).setEntropyBitsRequired(
|
|
|
+ ENTROPY_BITS_REQUIRED).buildCTR(cipher, CIPHER_LEN, null, reSeed);
|
|
|
+ }
|
|
|
+}
|