URL myUrl = new URL("https://www.....");
网站SSL证书已过期。如何避免它并使URL()工作?
答案 0 :(得分:20)
您应该构建一个包含默认信任管理器的TrustManager
,捕获CertificiateExpiredException
并忽略它。
注意:正如this answer中详细说明的那样,这是否安全非常依赖于实现。特别是,在完成其他所有操作后,它依赖于最后完成的日期验证。
这些方面应该有效:
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
// Initialise the TMF as you normally would, for example:
tmf.init((KeyStore)null);
TrustManager[] trustManagers = tmf.getTrustManagers();
final X509TrustManager origTrustmanager = (X509TrustManager)trustManagers[0];
TrustManager[] wrappedTrustManagers = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return origTrustmanager.getAcceptedIssuers();
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
origTrustmanager.checkClientTrusted(certs, authType);
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
try {
origTrustmanager.checkServerTrusted(certs, authType);
} catch (CertificateExpiredException e) {}
}
}
};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, wrappedTrustManagers, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
当证书出现问题时,信任管理员会抛出CertificateException
(有关详细信息,请参阅子类)。具体到你想要捕捉/忽略的内容。您可能需要检查您确实需要验证的所有内容,或者您必须手动验证它。任何比这更放松的事情(特别是,没有做任何事情,因此不会抛出任何异常)将完全忽略证书验证和验证,这与使用匿名密码套件或忽略身份验证大致相同。这会破坏使用SSL / TLS的安全目的(而不是在到期日时更灵活)。
答案 1 :(得分:2)
您必须创建一个将忽略过期证书的自定义X509验证程序。事实上,不会进行检查。
从此处获取的代码:http://exampledepot.com/egs/javax.net.ssl/TrustAll.html
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}
// Now you can access an https URL without having the certificate in the truststore
// It should work with expired certificate as well
try {
URL myUrl = new URL("https://www.....");
} catch (MalformedURLException e) {
}
答案 2 :(得分:1)
我写了一个自定义的TrustManager来解决这个问题,你可以在https://gist.github.com/divergentdave/9a68d820e3610513bd4fcdc4ae5f91a1看到它。此TrustManager将违规的X509Certificate包装在另一个类中,以禁用过期检查,同时保留所有其他验证。 (即匹配主机名,链到受信任的CA,签名有效等)