如何在Java中以编程方式检查SSL证书到期日期



我需要从Java网站上的SSL证书提取到期日期,应支持两者受信任和自我签名的证书,例如:1.受到信任https://github.com2.自我签名https://mms.nw.ru/

我已经将一些代码复制为:

import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class SSLTest {
    public static void main(String [] args) throws Exception {
        // configure the SSLContext with a TrustManager
        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
        SSLContext.setDefault(ctx);
        URL url = new URL("https://github.com");//https://mms.nw.ru
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
        System.out.println(conn.getResponseCode());
        Certificate[] certs = conn.getServerCertificates();
        for (Certificate cert :certs){
            System.out.println(cert.getType());
            System.out.println(cert);
        }
        conn.disconnect();
    }
    private static class DefaultTrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
}

问题是:

  1. 如何从证书中解析到期日期,在我的代码中,toString()确实输出了日期,但是很难解析。

  2. 如何确定证书链,例如,带有链条的GitHub证书3,我怎么知道从哪个证书获得到期日期?

如何从证书中解析到期日期

将其施放到X509Certificate并致电getNotAfter()

如何确定证书链,例如,带链条的GitHub证书

你已经知道了。这就是Certificate[]阵列,正如它在Javadoc中所说的。

我怎么知道从哪个证书获得到期日期?

阅读Javadoc。"同行自己的证书首先是任何证书机构"。

但是,我不知道您为什么这样做。Java应该已经为您完成了所有事情。

,请丢弃不安全和不正确的信任管理者实施。处理自签名证书的正确方法是将其导入客户端信任库。还请丢弃您的不安全的主机名称,并使用默认的主机或安全的主机。如果您不希望它安全,为什么还要完全使用HTTP?

请确保将开始/结束线附加到PEM格式,否则Java不了解它。

public class CertTest {
    public static final String cert = "-----BEGIN CERTIFICATE-----n<CERT_DATA>n-----END CERTIFICATE-----";
    public static void main(String[] args){
        try {
            X509Certificate myCert = (X509Certificate)CertificateFactory
                     .getInstance("X509")
                     .generateCertificate(
                                       // string encoded with default charset
                    new ByteArrayInputStream(cert.getBytes())
                     );
            System.out.println(myCert.getNotAfter());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

以kotlin方式,它应该看起来像这样:

fun certInformation(aURL: String) {
    val destinationURL = URL(aURL)
    val conn = destinationURL.openConnection() as HttpsURLConnection
    conn.connect()
    val certs = conn.serverCertificates
    for (cert in certs) {
        println("Certificate is: $cert")
        if (cert is X509Certificate) {
            println(cert.issuerDN.name)
            println(cert.notAfter)
            println(cert.notBefore)
        }
    }
}

最新更新