8.9
luodangjia
2024-09-03 2855ae89d2ab6268e1edc42c3e9d7e73c8e7259e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */
 
package com.ruoyi.admin.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);
    }
}