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

我需要从Java网站上的SSL证书中提取到期日期,应该支持可信和自签名证书,例如:1.trusted https://github.com 2.self-signed 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. 如何确定证书链,例如带链3的github证书,我如何知道从哪个证书中获取到期日期?

如何解析证书的到期日期

将其转换为X509Certificate并调用getNotAfter()

如何确定证书链,例如带链的github证书

你有它。 就像在Javadoc中所说的那样,这就是Certificate[]数组。

我怎么知道哪个证书可以从哪个证书到期?

阅读Javadoc 。 “对等方自己的证书首先跟随任何证书颁发机构”。

但是我不知道你为什么这么做。 Java应该已经为您完成了所有工作。

请丢掉那些不安全和不正确的TrustManager实现。 处理自签名证书的正确方法是将它们导入客户端信任库。 还请丢弃您不安全的HostnameVerifier,并使用默认的或安全的。 如果您不希望它安全,为什么要使用HTTPS呢?

确保将开始/结束行附加到PEM格式,否则java不理解它。

 public class CertTest { public static final String cert = "-----BEGIN CERTIFICATE-----\n\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(); } } }