You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中如何从HTTPS响应获取SSL/TLS证书以验证部署有效性?

证书部署后验证方案(Java环境)

针对你实现证书自动化服务、需要验证部署后证书信息的需求,这里提供几种实用方案:

一、现成工具/API直接用,不用自己写Socket

Java生态里有不少封装好的工具,完全不需要处理底层握手逻辑:

1. JDK自带HttpsURLConnection

这是最轻量化的方案,零额外依赖,直接获取服务器证书链:

import javax.net.ssl.HttpsURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.util.Date;

public class CertValidator {
    public static void main(String[] args) throws Exception {
        URL targetUrl = new URL("https://your-deployed-domain.com");
        HttpsURLConnection conn = (HttpsURLConnection) targetUrl.openConnection();
        conn.connect();
        
        // 提取服务器证书链,第一个通常是目标服务器的证书
        X509Certificate[] certChain = (X509Certificate[]) conn.getServerCertificates();
        if (certChain.length > 0) {
            X509Certificate serverCert = certChain[0];
            System.out.println("证书颁发日期: " + serverCert.getNotBefore());
            System.out.println("证书过期日期: " + serverCert.getNotAfter());
            // 还可以验证证书主题、颁发者DN等信息,匹配你的预期配置
        }
        conn.disconnect();
    }
}

2. Apache HttpClient(适合复杂HTTP场景)

如果需要配置超时、代理或者更灵活的请求参数,用Apache HttpClient也能轻松拿到证书:

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.SSLSession;
import java.security.cert.X509Certificate;

public class HttpClientCertChecker {
    public static void main(String[] args) throws Exception {
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(new SSLConnectionSocketFactory(SSLContexts.createDefault()) {
                    @Override
                    protected void prepareSocket(javax.net.ssl.SSLSocket socket) {
                        // 握手完成后从会话中提取证书
                        SSLSession session = socket.getSession();
                        try {
                            X509Certificate[] certChain = (X509Certificate[]) session.getPeerCertificates();
                            if (certChain.length > 0) {
                                X509Certificate serverCert = certChain[0];
                                System.out.println("颁发日期: " + serverCert.getNotBefore());
                                System.out.println("过期日期: " + serverCert.getNotAfter());
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                })
                .build();

        HttpGet request = new HttpGet("https://your-deployed-domain.com");
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            // 这里可以处理响应内容,证书信息已经在prepareSocket中获取
        }
    }
}

二、手动通过Socket实现(需要底层控制时)

如果确实要自己处理SSL握手流程,步骤很清晰:

  1. 建立普通Socket连接到目标端口(默认443)
  2. 包装成SSLSocket并触发握手
  3. 从SSLSession中提取证书信息
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.SSLSession;
import java.security.cert.X509Certificate;
import java.io.IOException;

public class RawSocketCertChecker {
    public static void main(String[] args) throws IOException {
        String targetHost = "your-deployed-domain.com";
        int targetPort = 443;

        SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
        try (SSLSocket sslSocket = (SSLSocket) factory.createSocket(targetHost, targetPort)) {
            // 主动触发SSL握手
            sslSocket.startHandshake();
            SSLSession session = sslSocket.getSession();
            
            X509Certificate[] certChain = (X509Certificate[]) session.getPeerCertificates();
            if (certChain.length > 0) {
                X509Certificate serverCert = certChain[0];
                System.out.println("颁发日期: " + serverCert.getNotBefore());
                System.out.println("过期日期: " + serverCert.getNotAfter());
            }
        }
    }
}

注意:默认SSLSocket会用系统信任库验证证书,如果是自签名证书会抛出SSLHandshakeException,这时候就需要用到你提到的自定义X509信任管理器。

三、自定义X509信任管理器实现客户端验证

当需要跳过默认信任校验(比如测试环境自签名证书),或者自定义验证逻辑时,实现X509TrustManager即可:

import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;

public class CustomCertTrustManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        // 客户端证书验证逻辑,不需要的话可以留空(根据你的服务需求调整)
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        // 自定义服务器证书验证规则,比如检查过期日期、颁发者等
        for (X509Certificate cert : chain) {
            // 检查证书是否过期
            if (cert.getNotAfter().before(new Date())) {
                throw new CertificateException("部署的证书已过期");
            }
            // 验证颁发者是否符合预期(示例)
            if (!cert.getIssuerDN().getName().contains("YourExpectedCA")) {
                throw new CertificateException("证书颁发者不符合预期");
            }
        }
    }

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

然后在创建SSL上下文时使用这个信任管理器:

// 构建自定义SSL上下文
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new CustomCertTrustManager()}, null);

// 给HttpsURLConnection用
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

// 给SSLSocket用
SSLSocketFactory customSocketFactory = sslContext.getSocketFactory();

内容的提问来源于stack exchange,提问作者DevDengChao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 12:18:26