我们有一个 Java 应用程序,我们需要忽略过期的自签名证书,但是我们无法修改代码来执行此操作。我想知道是否有我们可以在启动时提供的系统属性或环境变量,这将允许我们暂时忽略所有过期的证书,或者甚至更具体,并在外部提供我们希望过期的特定证书忽略。
有人有任何可行的想法吗?
我们有一个 Java 应用程序,我们需要忽略过期的自签名证书,但是我们无法修改代码来执行此操作。我想知道是否有我们可以在启动时提供的系统属性或环境变量,这将允许我们暂时忽略所有过期的证书,或者甚至更具体,并在外部提供我们希望过期的特定证书忽略。
有人有任何可行的想法吗?
下面是结合java-ignore expired ssl certificate和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 启动参数。
另请参阅SSL 和 TLS 之间的区别及其在 Java和Java 8 中的用法 SSLContext.getInstance("TLSv1.2") 是什么意思?SSLContext.getInstance()
在你的情况下为适当的论据。
另请注意,具有过期证书的服务器也可能自己检查匹配的客户端证书的过期:
引起:javax.net.ssl.SSLHandshakeException:收到致命警报:com.sun.net.ssl.internal 的 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) 的证书过期。 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)
如果您遇到这样的堆栈跟踪,那么在不接触服务器的情况下就无法缓解问题。正确的解决方案是重新签发具有未来到期日的证书。