How to ignore expired certificates from outside a Java application?(如何忽略来自 Java 应用程序外部的过期证书?)
问题描述
我们有一个 Java 应用程序需要忽略过期的自签名证书,但是我们无法修改代码来执行此操作.我想知道是否有我们可以在启动时提供的系统属性或环境变量,这将允许我们暂时忽略所有过期的证书,或者甚至更具体,并在外部提供我们希望过期的特定证书忽略.
We have a Java application that we need to ignore an expired self-signed cert, however we cannot modify the code to do this. I wondering if there was a System Property or environment variable that we could provide at start up that would allow us to have all expired cert's ignored for now, or even be more specific and provide externally the specific cert that we would like to have the expiration ignored.
有人有任何可行的想法吗?
Anyone have any ideas that would work?
推荐答案
这里是结合java - 忽略过期的 ssl 证书 和 Java SSL:如何禁用主机名验证.
public class IgnoreExpiredServerCertificateAgent {
public static void premain(String args, Instrumentation inst) throws Exception {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
TrustManager[] trustManagers = tmf.getTrustManagers();
final X509TrustManager origTrustManager = (X509TrustManager) trustManagers[0];
TrustManager[] wrappedTrustManagers = new TrustManager[]{
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return origTrustManager.getAcceptedIssuers();
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
origTrustManager.checkClientTrusted(certs, authType);
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
try {
origTrustManager.checkServerTrusted(certs, authType);
} catch (CertificateExpiredException ignored) {
}
}
}
};
//SSLContext sc = SSLContext.getDefault();
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, wrappedTrustManagers, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
}
然后只需将 -javaagent:IgnoreExpiredServerCertificateAgent.jar
添加到程序的 java 启动参数中.
Then just add -javaagent:IgnoreExpiredServerCertificateAgent.jar
to program's java startup arguments.
另请参阅 SSL 和 TLS 之间的区别及其Java 中的用法 和 Java 8 SSLContext.getInstance(TLSv1.2")这是什么意思?在您的情况下为 SSLContext.getInstance()
提供适当的参数.
See also Difference between SSL and TLS and their usage in Java and Java 8 SSLContext.getInstance("TLSv1.2") what does it mean? for appropriate argument for SSLContext.getInstance()
in your case.
还要注意,证书过期的服务器也可以自己检查匹配的客户端证书是否过期:
Also note that the server with expired certificate may also itself check the expiry of the matching client certificate:
引起:javax.net.ssl.SSLHandshakeException:收到致命警报:证书过期时间com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)在com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)在com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1822)在com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1004)在com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)在com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215)在com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199)在sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)在sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)在sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195)在java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)在sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318)
Caused by:javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_expired at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1822) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1004) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318)
如果您遇到这样的堆栈跟踪,那么在不接触服务器的情况下就无法缓解问题.正确的解决方案是重新颁发具有未来到期日的证书.
If you meet such stacktrace then there is no way to mitigate the problem without touching the server. And the proper solution would be to reissue the certificate with future expiry date.
这篇关于如何忽略来自 Java 应用程序外部的过期证书?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何忽略来自 Java 应用程序外部的过期证书?
基础教程推荐
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01