[英]how to check SSL certificate expiration date programmatically in Java
我需要从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;
}
}
}
问题是:
如何从证书解析到期日期,在我的代码中,toString() 确实输出了日期,但很难解析。
如何确定证书链,例如,带有链 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<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)
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.