【HTTPS】1、使用jdk实现https接口调用和证书验证

概述

我们之前调用https都是不做证书验证的,因为我们实现X509TrustManager方法的时候并没有具体实现里面的方法,而是不实现,那么这就会导致一个问题,那就是证书有正确性是没有得到有效验证的
常规的方法我们如果想验证的话,那就是不实现X509TrustManager,用jdk自带的方法进行接口调用,但是这个要求我们用keytools对第三方的证书进行导入,并且会对jdk自带的信任库有侵入性修改,这个软件每次安全都得重新导入对应的证书
那么有没有版本不需要手动导入操作,也能进行对端证书验证呢?
因为客户端证书是可以再浏览器上直接下载的,那么如果我们能用代码实现证书的下载,并且安装到本地,不就可以实现证书的自动安装了么?(当前这样做也不安全,因为并不是所有的证书都需要安装,但是我们可以加一个开关或者一个业务上配置,判断那些网站是可以信任,那些不需要信任,然后对信任的网站进行自动证书安装)

当前这样做也不安全,因为并不是所有的证书都需要安装,但是我们可以加一个开关或者一个业务上配置,判断那些网站是可以信任,那些不需要信任,然后对信任的网站进行自动证书安装
当然如果是互联网这个做法就有点脱裤子放屁的嫌疑,但是如果这个是局域网/内网的情况下就很有效果了

代码实现

用来保存证书的代码

package https.util;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

/**
 * 功能描述
 *
 * @since 2022-05-09
 */
public class SaveCertManager implements X509TrustManager {

    private final X509TrustManager tm;
    public X509Certificate[] chain;

    public SaveCertManager(X509TrustManager tm) {
        this.tm = tm;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        this.chain = chain;
        tm.checkClientTrusted(chain, authType);
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        this.chain = chain;
        tm.checkServerTrusted(chain, authType);
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
}

用来校验证书的代码

package https.util;

import java.security.cert.CertificateException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.Arrays;

import javax.net.ssl.X509TrustManager;

/**
 * 功能描述
 *
 * @since 2022-05-09
 */
public class CheckCertManager  implements X509TrustManager {

    private final X509TrustManager tm;
    public X509Certificate[] chain;
    // 吊销列表
    private X509CRL[] x509CRLs;

    public CheckCertManager(X509TrustManager tm) {
        this.tm = tm;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        tm.checkClientTrusted(chain, authType);

        // 吊销证书验证
        if (x509CRLs != null) {
            Arrays.stream(chain).forEach(cert -> {
                Arrays.stream(x509CRLs).forEach(x509CRL -> {
                    if (x509CRL.isRevoked(cert)) {
                        // 证书已经吊销
                        System.out.println("证书已经吊销");
                    }
                });
            });
        }
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        tm.checkClientTrusted(chain, authType);

        // 吊销证书验证
        if (x509CRLs != null) {
            Arrays.stream(chain).forEach(cert -> {
                Arrays.stream(x509CRLs).forEach(x509CRL -> {
                    if (x509CRL.isRevoked(cert)) {
                        // 证书已经吊销
                        System.out.println("证书已经吊销");
                    }
                });
            });
        }
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }

    public X509CRL[] getX509CRLs() {
        return x509CRLs;
    }

    public void setX509CRLs(X509CRL[] x509CRLs) {
        this.x509CRLs = x509CRLs;
    }
}

package https.util;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.text.Normalizer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import sun.security.x509.CRLDistributionPointsExtension;
import sun.security.x509.URIName;
import sun.security.x509.X509CertImpl;

/**
 * 功能描述
 *
 * @since 2022-05-09
 */
public class HttpsUtil2022 {

    /**
     * 默认jdk的证书仓库名称
     */
    private static String CERTS_SOURCE_FILE = "jssecacerts";

    /**
     * 默认的ca证书文件名称
     */
    private static String CERTS_SOURCE_CA_FILE = "cacerts";

    public static String sendPostWithCheckCertAndRevokedCheck(Map params) throws UnsupportedEncodingException {
        ByteArrayOutputStream ans = new ByteArrayOutputStream();
        // https请求,自动加载证书,并进行证书有效期验证,并且自动加载crl证书分发点,然后进行证书吊销验证
        // 1. 判断是否需要进行证书下载
        // 2. 下载crl证书吊销分发点
        boolean checkres = checkAndInstallCertAndCrl(params);
        // 3. 创建https连接,并且使用指定的证书进行有效期验证,并且使用指定的证书校验是否吊销
        // 1.读取jks证书文件
        String templateHome = MapUtils.getString(params, "templateHome");
        String filePath = templateHome + File.separator + MapUtils.getString(params, "fileName");
        String crlFilePath = templateHome + File.separator + "crl";
        String sourcePasswd = MapUtils.getString(params, "sourcePasswd");
        String url = MapUtils.getString(params, "url");
        String host = MapUtils.getString(params, "host");
        String request = MapUtils.getString(params, "request");

        File certsFile = new File(filePath);
        if (!certsFile.isFile()) {
            filePath = replaceCRLF(System.getProperty("java.home") + File.separator + "lib" + File.separator + "security");
            filePath = Normalizer.normalize(filePath, Normalizer.Form.NFKC);
            File dir = new File(filePath);
            certsFile = new File(dir, CERTS_SOURCE_FILE);
            if (!certsFile.isFile()) {
                certsFile = new File(dir, CERTS_SOURCE_CA_FILE);
            }
            filePath = certsFile.getPath();
            sourcePasswd = MapUtils.getString(params, "jdkcertPasswd");
        }

        try (InputStream inputStream = new FileInputStream(filePath)) {
            URL url1 = new URL(url);
            HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url1.openConnection();

            if (checkres) {
                // 这里需要从新加载,不然读取的是老的content
                // 3.读取证书,初始化ssl
                // 默认是jks的证书
                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                // 加载
                keyStore.load(inputStream, sourcePasswd.toCharArray());
                SSLContext sslContext = SSLContext.getInstance("TLSv1.2", "SunJSSE");
                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                trustManagerFactory.init(keyStore);
                X509TrustManager x509TrustManager = (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
                CheckCertManager checkCertManager = new CheckCertManager(x509TrustManager);

                // 读取吊销列表
                File crldir = new File(crlFilePath);
                if (crldir.exists() && crldir.isDirectory() && crldir.listFiles() != null) {
                    File[] crlFiles = crldir.listFiles();
                    X509CRL[] x509CRLs = new X509CRL[crlFiles.length];
                    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                    InputStream crlInputStream = null;
                    for (int i = 0; i < crlFiles.length; ++i) {
                        crlInputStream = new FileInputStream(crlFiles[i]);
                        X509CRL crl = (X509CRL) certificateFactory.generateCRL(crlInputStream);
                        crlInputStream.close();
                        x509CRLs[i] = crl;
                    }
                    checkCertManager.setX509CRLs(x509CRLs);
                }
                sslContext.init(null, new TrustManager[]{checkCertManager}, SecureRandom.getInstanceStrong());
                String finalHost = host;
                httpsURLConnection.setHostnameVerifier((str, sslSession) -> sslVerify(str, "true", finalHost));
                httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
            }
            // 4.&#x53D1;&#x9001;https&#x8BF7;&#x6C42;&#xFF0C;&#x57FA;&#x4E8E;&#x5F53;&#x524D;&#x5DF2;&#x7ECF;&#x5B89;&#x88C5;&#x7684;&#x8BC1;&#x4E66;
            // &#x8BBE;&#x7F6E;&#x8BF7;&#x6C42;&#x5934;
//            httpsURLConnection.setRequestProperty("Content-Type", "application/json");

            // &#x8BBE;&#x7F6E;&#x8BF7;&#x6C42;&#x5934;
            Map<string, string> heads = (Map) params.get("heads");
            if (heads == null) {
                heads = new HashMap<>();
            }
            for (Map.Entry<string, string> entry : heads.entrySet()) {
                httpsURLConnection.addRequestProperty(entry.getKey(), entry.getValue());
            }

            // &#x8BBE;&#x7F6E;&#x8BF7;&#x6C42;&#x65B9;&#x6CD5; requestMethod
            httpsURLConnection.setRequestMethod(MapUtils.getString(params, "requestMethod", "GET"));
//            httpsURLConnection.setDoOutput(true);
            httpsURLConnection.connect(); // &#x5EFA;&#x7ACB;&#x5B9E;&#x9645;&#x8FDE;&#x63A5;

            // &#x53D1;&#x9001;&#x8BF7;&#x6C42;&#x6570;&#x636E;
            InputStream urlInputStream;
            if (StringUtils.isNotBlank(request)) {
                OutputStream urlOutputStream = httpsURLConnection.getOutputStream();
                urlOutputStream.write(request.getBytes());
                urlOutputStream.flush();
            }

            // &#x83B7;&#x53D6;&#x8FD4;&#x56DE;&#x7ED3;&#x679C;
            int index;
            byte[] bytes = new byte[2048];
            if (httpsURLConnection.getResponseCode() == 200) {
                // &#x8BF7;&#x6C42;&#x6210;&#x529F;&#x8F93;&#x51FA;&#x6570;&#x636E;
                urlInputStream = httpsURLConnection.getInputStream();
                // &#x8BFB;&#x53D6;&#x6570;&#x636E;

            } else {
                // &#x8F93;&#x51FA;&#x9519;&#x8BEF;&#x4FE1;&#x606F;
                urlInputStream = httpsURLConnection.getErrorStream();
            }
            // &#x8FD4;&#x56DE;&#x6570;&#x636E;
            while ((index = urlInputStream.read(bytes)) != -1) {
                // &#x5199;&#x51FA;&#x6570;&#x636E;&#x96C6;
                ans.write(bytes, 0, index);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ans.toString();
    }

    private static boolean sslVerify(String str, String isCheck, String hostname) {
        if ("false".equals(isCheck)) {
            return true;
        }
        if (StringUtils.isNotEmpty(hostname)) {
            if (check(str, hostname)) {
                return true;
            }
        }
        return false;
    }

    private static boolean check(String str, String hostname) {
        if (hostname.contains(",")) {
            String[] hostnames = hostname.split(",");
            if (checkForeach(str, hostnames)) {
                return true;
            }
        } else {
            if (str.equalsIgnoreCase(hostname)) {
                return true;
            }
        }
        return false;
    }

    private static boolean checkForeach(String str, String[] hostnames) {
        for (String host : hostnames) {
            if (str.equalsIgnoreCase(host)) {
                return true;
            }
        }
        return false;
    }

    private static boolean checkAndInstallCertAndCrl(Map params) {
        boolean ans = true;
        // &#x529F;&#x80FD;&#xFF1A; &#x5224;&#x65AD;&#x662F;&#x5426;&#x9700;&#x8981;&#x8FDB;&#x884C;&#x8BC1;&#x4E66;&#x4E0B;&#x8F7D; &#xFF0C;&#x4E0B;&#x8F7D;crl&#x8BC1;&#x4E66;&#x540A;&#x9500;&#x5206;&#x53D1;&#x70B9;
        // 1. &#x83B7;&#x53D6;&#x8BC1;&#x4E66;&#x8DEF;&#x5F84;
        // 1. &#x5B58;&#x653E;&#x8BC1;&#x4E66;&#x8BA4;&#x8BC1;&#x4FE1;&#x606F;&#x8DEF;&#x5F84;
        String templateHome = MapUtils.getString(params, "templateHome");
        String filePath = templateHome + File.separator + MapUtils.getString(params, "fileName");
        File certsFile = new File(filePath);
        String sourcePasswd = MapUtils.getString(params, "sourcePasswd");
        String protocol = MapUtils.getString(params, "sslVersion");
//        host, port
        String host = MapUtils.getString(params, "host");
        int port = MapUtils.getInteger(params, "port");

        if (!certsFile.isFile()) {
            filePath = replaceCRLF(System.getProperty("java.home") + File.separator + "lib" + File.separator + "security");
            filePath = Normalizer.normalize(filePath, Normalizer.Form.NFKC);
            File dir = new File(filePath);
            certsFile = new File(dir, CERTS_SOURCE_FILE);
            if (!certsFile.isFile()) {
                certsFile = new File(dir, CERTS_SOURCE_CA_FILE);
            }
            sourcePasswd = MapUtils.getString(params, "jdkcertPasswd");
            ans = false;
        }
        // 2. &#x5F53;&#x524D;&#x8BC1;&#x4E66;&#x5E93;&#x4E2D;&#x662F;&#x5426;&#x5DF2;&#x7ECF;&#x5BF9;&#x8FD9;&#x4E2A;&#x7F51;&#x7AD9;&#x4FE1;&#x4EFB;&#x4E86; --
        OutputStream outputStream = null;
        try (InputStream inputStream = new FileInputStream(certsFile)) {
            // 3. &#x5C1D;&#x8BD5;&#x4E00;&#x6B21;&#x8FDE;&#x63A5;&#xFF0C;&#x5E76;&#x83B7;&#x53D6;&#x8BC1;&#x4E66;&#x5BF9;&#x8C61;
            // &#x9ED8;&#x8BA4;&#x662F;jks&#x7684;&#x8BC1;&#x4E66;
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            // &#x52A0;&#x8F7D;
            keyStore.load(inputStream, sourcePasswd.toCharArray());
            // 2.&#x6784;&#x5EFA;TLS&#x8BF7;&#x6C42;
            SSLContext sslContext = SSLContext.getInstance(protocol, "SunJSSE");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            // &#x8BFB;&#x53D6;&#x9ED8;&#x8BA4;&#x7684;&#x7BA1;&#x7406;&#x5668;
            X509TrustManager x509TrustManager = (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
            SaveCertManager trustCertsSaveManager = new SaveCertManager(x509TrustManager);
            sslContext.init(null, new TrustManager[]{trustCertsSaveManager}, SecureRandom.getInstanceStrong());
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            // 4.-1 &#x5224;&#x65AD;&#x662F;&#x5426;&#x9700;&#x8981;&#x5B89;&#x88C5;
            // 3.&#x5224;&#x65AD;&#x662F;&#x5426;&#x9700;&#x8981;&#x5B89;&#x88C5;
            // 4.&#x8BFB;&#x53D6;&#x8BC1;&#x4E66;&#x94FE;&#xFF0C;&#x4F9D;&#x6B21;&#x5B89;&#x88C5;&#x8F93;&#x5165;&#x5230;&#x6587;&#x4EF6;&#x4E2D;
            if (!needInstall(sslSocketFactory, host, port)) {
                return ans;
            }
            // &#x8BFB;&#x53D6;&#x9700;&#x8981;&#x5B89;&#x88C5;&#x7684;&#x8BC1;&#x4E66;&#x94FE;
            X509Certificate[] x509Certificates = trustCertsSaveManager.chain;
            if (x509Certificates == null) {
                return false;
            }

            // 4. &#x83B7;&#x53D6;&#x8BC1;&#x4E66;&#x7684;&#x540A;&#x9500;&#x5217;&#x8868;
            outputStream = new FileOutputStream(filePath);
            for (int i = 0; i < x509Certificates.length; i++) {
                X509CertImpl x509Cert = (X509CertImpl) x509Certificates[i];
                // &#x83B7;&#x53D6;crl&#x5206;&#x53D1;&#x70B9;&#xFF0C;&#x7136;&#x540E;&#x4E0B;&#x8F7D;&#x8BC1;&#x4E66;&#x6587;&#x4EF6;
                CRLDistributionPointsExtension crlDistributionPointsExtension = x509Cert.getCRLDistributionPointsExtension();
                // &#x4E0B;&#x8F7D;&#x6240;&#x6709;
                // 5. &#x4E0B;&#x8F7D;&#x4FDD;&#x5B58;&#x8BC1;&#x4E66;&#x7684;&#x540A;&#x9500;&#x5217;&#x8868;
                downloadCrlAndCreateDir(crlDistributionPointsExtension, templateHome);

                // 6. &#x8F93;&#x51FA;&#x4FDD;&#x5B58;&#x8BC1;&#x4E66;&#x5BF9;&#x8C61;
                String alias = host + "-" + i + 1;
                X509Certificate x509Certificate = x509Certificates[i];
                // &#x52A0;&#x8F7D;&#x8BC1;&#x4E66;
                keyStore.setCertificateEntry(alias, x509Certificate);
                // &#x8F93;&#x51FA;&#x5230;&#x8BC1;&#x4E66;&#x6587;&#x4EF6;
                keyStore.store(outputStream, MapUtils.getString(params, "sourcePasswd").toCharArray());
            }
            outputStream.flush();
            ans = true;
        } catch (Exception e) {
            ans = false;
            e.printStackTrace();
        } finally {
            closeStream(outputStream, null);
        }
        return ans;
    }

    private static void closeStream(OutputStream outputStream, InputStream inputStream) {
        // &#x5173;&#x95ED;&#x6D41;
        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
//                LOGGER.error("Exception:" + e);
            }
            outputStream = null;
        }

        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
//                LOGGER.error("Exception:" + e);
                e.printStackTrace();
            }
            inputStream = null;
        }
    }

    private static void downloadCrlAndCreateDir(CRLDistributionPointsExtension crlDistributionPointsExtension, String basePath) throws IOException {
        if (crlDistributionPointsExtension == null) {
            return;
        }
        // &#x4E0B;&#x8F7D;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date();
        // &#x83B7;&#x53D6;&#x540A;&#x9500;&#x5730;&#x5740;
        crlDistributionPointsExtension.get(CRLDistributionPointsExtension.POINTS).forEach(distributionPoint -> {
            // &#x5FAA;&#x73AF;&#x6BCF;&#x4E00;&#x4E2A;&#x540A;&#x9500;&#x5217;&#x8868;
            int[] index = {0};
            distributionPoint.getFullName().names().forEach(generalName -> {
                URIName uri = (URIName) generalName.getName();
                // &#x4E0B;&#x8F7D;uri
                try {
                    downloadCrl(uri, basePath + File.separator + "crl" + File.separator + simpleDateFormat.format(date) + index[0] + ".crl");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            index[0]++;
        });
    }

    private static void downloadCrl(URIName uri, String outpath) throws IOException {
        URL url = new URL(uri.getURI().toString());
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        InputStream netinput = httpURLConnection.getInputStream();
        // &#x5224;&#x65AD;&#x8DEF;&#x5F84;&#x662F;&#x5426;&#x5B58;&#x5728;
        File outfile = new File(outpath);
        if (!outfile.exists()) {
            createFileAndDir(outfile);
        }
        FileOutputStream fileOutputStream = new FileOutputStream(outpath);

        // &#x8FD4;&#x56DE;&#x6570;&#x636E;
        int index;
        byte[] bytes = new byte[2048];
        while ((index = netinput.read(bytes)) != -1) {
            // &#x5199;&#x51FA;&#x6570;&#x636E;&#x96C6;
            fileOutputStream.write(bytes, 0, index);
        }
        fileOutputStream.flush();
    }

    // &#x521B;&#x5EFA;&#x8DEF;&#x5F84;&#x548C;&#x6587;&#x4EF6;
    private static void createFileAndDir(File file) throws IOException {
        if (file.exists()) {
            return;
        }

        // &#x5982;&#x679C;&#x4E0D;&#x5B58;&#x5728;
        if (file.isDirectory()) {
            file.mkdirs();
        }

        // &#x5982;&#x679C;&#x4E0D;&#x662F;&#x76EE;&#x5F55;
        if (file.getParentFile().exists()) {
            file.createNewFile();
        }

        // &#x5982;&#x679C;&#x76EE;&#x5F55;&#x90FD;&#x4E0D;&#x5B58;&#x5728;
        //&#x521B;&#x5EFA;&#x4E0A;&#x7EA7;&#x76EE;&#x5F55;
        file.getParentFile().mkdirs();
        file.createNewFile();
    }

    private static boolean needInstall(SSLSocketFactory sslSocketFactory, String host, int port) throws IOException {
        boolean needInstall = false;
        SSLSocket sslSocket = null;
        try {
            sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port);
            sslSocket.setSoTimeout(3000);
            sslSocket.startHandshake();
            sslSocket.close();
        } catch (SSLException e) {
//            LOGGER.info("", e);
            needInstall = true;
        } finally {
            sslSocket.close();
        }
        return needInstall;
    }

    /**
     * &#x9632;&#x6B62; replaceCRLF&#x6CE8;&#x5165;
     *
     * @param message &#x53C2;&#x6570;
     * @return str
     */
    public static String replaceCRLF(String message) {
        if (StringUtils.isBlank(message)) {
            return "";
        }
        return message.replace('\n', '_').replace('\r', '_');
    }

}

</string,></string,>

网站实验

@Test
    public void testHttpsNew() throws UnsupportedEncodingException {
        // https://github.com/c
        // https://t.bilibili.com/
        Map params = new HashMap();
        params.put("host", "api.bilibili.com");
        params.put("port", 443);
        params.put("sslVersion", "TLSv1.2");
        params.put("protocol", "https");
        params.put("urlPath", "/");
        params.put("timeOut", 3000);
        params.put("fileName", "test.jks");
        params.put("certsPasswd", "changit");
//      sourcePasswd2
        params.put("sourcePasswd", "changit");
        params.put("jdkcertPasswd", "changeit");
        params.put("templateHome", "C:\\Users\\Administrator\\Desktop\\tmp\\https");
        params.put("revoked", "diaoxiao.crl");
        params.put("requestMethod", "GET");
        params.put("url", "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all?timezone_offset=-480&type=video&page=1");

        // &#x8BBE;&#x7F6E;&#x8BF7;&#x6C42;&#x5934;,&#x8FD9;&#x91CC;&#x6211;&#x7528;&#x7684;&#x6211;&#x81EA;&#x5DF1;B&#x7AD9;&#x7684;&#x56DE;&#x8BDD;&#xFF0C;&#x6240;&#x4EE5;&#x5C31;&#x9690;&#x85CF;&#x4E00;&#x4E0B;
        Map heads = new HashMap();
        heads.put("cookie", "SESSDATA=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;");
        heads.put("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36");
        params.put("heads", heads);

        String res = HttpsUtil2022.sendPostWithCheckCertAndRevokedCheck(params);
        System.out.println(res);
    }

返回的结果:

【HTTPS】1、使用jdk实现https接口调用和证书验证

最后说一句
其实这个代码如果debug就会发现,并没有走真正的证书校验的逻辑,但是我暂时又找不到不信任证书的网站,自己搭建的话又比较耗时间,所以这里就直接给出代码,大家可以线下验证一下,至于为什么不走,应该是走的互联网公证的CA证书可以直接连接,不需要走本地的证书校验了
还有一个就是证书吊销那块的逻辑需要说一下(分2种,一个CRL,一个OCSP):
证书吊销分2中,我这里是本地设置证书吊销库
这两种的差别是一个是本地校验,一个是远程网站接口校验,
1.如果本地校验,就需要远程下载一个crl库,然后进行比较,比较耗时
2.OCSP的话,就需要能通外网,通过外网的OCSP接口进行校验证书是否吊销,有网络要求
分别对应的在证书中2个扩展信息,这里B站的话就是第二种,第一种一般是自己制作的证书会走这种方式了
X.509 证书扩展:CRL Distribution Points
X.509 证书扩展:authorityInfoAccess

【HTTPS】1、使用jdk实现https接口调用和证书验证

综上:
最好的版本其实应该就是提前下载/准备好CRL证书文件,然后本地直接一次性加载,后续就直接用,这样既不需要在认证的时候再去下载耗时,也不需要通外网进行接口认证

Original: https://www.cnblogs.com/cutter-point/p/16273245.html
Author: cutter_point
Title: 【HTTPS】1、使用jdk实现https接口调用和证书验证

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/713178/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 计算机的基本认识

    所有图片均为西部开源所有,仅作为随笔所用。 计算机是什么? 计算机的硬件组成 装机 主要设备 有CPU,内存(硬盘,内存条),主板,电脑就能跑起来了CPU拥有核显的话可以不用再装显…

    技术杂谈 2023年6月21日
    065
  • 最长公共子序列

    很久之前就有研究这个算法 结果忘记上传了 哈哈 前天看到好多同学需要这个算法 所以 来吧 写一写 先来看下 什么是公共子序列 我直接来一张图 相信大家就明白了 当然 图片是百度到的…

    技术杂谈 2023年7月23日
    071
  • Docker 容器中安装 Docker

    本文讲的是在Docker中安装Ubuntu容器,然后在这个Ubuntu容器中再安装Docker。或许这样可以省下买服务器的钱,当然这只是为了学习测试使用,真正项目上还是需要买服务器…

    技术杂谈 2023年7月10日
    073
  • SpringBoot自定义Banner信息

    SpringBoot自定义Banner信息 一、介绍 本文主要介绍使用springboot框架时,我们可以自定义我们项目的相关信息,例如启动图、启动时的版本号等。 二、自定义ban…

    技术杂谈 2023年6月21日
    0100
  • 百套响应式前端网站模板源码下载建站视频教程

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    技术杂谈 2023年7月11日
    065
  • 字节一面:事务还没提交的时候,redolog 能不能被持久化到磁盘呢?

    又是被自己菜醒的一天,总结面经看到这题目听都没听过,打开百度就像吃饭一样自然 老规矩,背诵版在文末。点击阅读原文可以直达我收录整理的各大厂面试真题 首先,咱需要明白的是,啥是持久化…

    技术杂谈 2023年7月25日
    0205
  • 【LEETCODE】72、分割回文串 III 第1278题

    package y2019.Algorithm.dynamicprogramming.hard; /** * @Auther: xiaof * @Date: 2019/12/11 …

    技术杂谈 2023年7月24日
    071
  • 有向图计数与GGF/2022.8.10闲话II

    《コバルトメモリーズ》海岸线は半透明半透明的海岸线,カモメが鸣いた,海鸥声声鸣叫着,ノイズまみれのラジオが歌うよ,掺杂着噪音的收音机正唱着歌,结构前の话,在很久以前,世界が全员喧哗…

    技术杂谈 2023年7月23日
    071
  • idea 的Low Memory问题

    今天使用 idea 出现 Low MemoryThe IDE is running low on memory and this might affect performance….

    技术杂谈 2023年5月31日
    0112
  • Phaser.js All In One

    Phaser.js All In One HTML5 Canvas 2D Game Engine Phaser.js https://phaser.io/ https://phas…

    技术杂谈 2023年6月1日
    063
  • 前端笔记知识

    笔记列表 基础知识 语言基础 DOM 计算机原理 CSS3 Git 网络与安全 网络 安全 性能与兼容性 数学 规范与概念 数据结构与算法 数据结构 算法 from: http:/…

    技术杂谈 2023年5月31日
    082
  • styleBinding属性详解

    属性 值 说明 width 默认值-1 -1:充满父元素的剩余宽度,即 父元素width – 父元素的paddingLeft – 父元素的paddingRi…

    技术杂谈 2023年6月1日
    063
  • 聊聊 Netty 那些事儿之 Reactor 在 Netty 中的实现(创建篇)

    本系列Netty源码解析文章基于 4.1.56.Final版本 在上篇文章《聊聊Netty那些事儿之从内核角度看IO模型》中我们花了大量的篇幅来从内核角度详细讲述了五种 IO&am…

    技术杂谈 2023年7月11日
    068
  • UVA12130 Summits(BFS + 贪心)

    UVA12130 Summits(BFS + 贪心) 题目大意:给你一个h ∗ w 的矩阵,矩阵的每一个元素都有一个值,代表这个位置的高度。 题目要求你找出这个图中有多少个位置是峰…

    技术杂谈 2023年5月31日
    076
  • Mysql重复数据查询置为空

    前两天产品有个需求,相同的商品因为价格不同而分开展示,但是明细还是算一条明细,具体区分展示出商品的价格和数量信息,其他重复的商品信息要置空。 需求并不难,用程序代码循环处理就可以了…

    技术杂谈 2023年7月11日
    085
  • bilibili动画下载视频批量改名(python)

    bilib应用 在微软商店中下载哔哩哔哩动画,虽然软件UI古老,但是贵在稳定和支持下载 安装以后搜索自己想要的视频,然后缓存下载 下载后进入下载的路径 视频文件重命名 打开自动命令…

    技术杂谈 2023年7月24日
    076
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球