java - 忽略过期的ssl证书

时间:2012-01-01 15:59:49

标签: java android url ssl

URL myUrl = new URL("https://www.....");

网站SSL证书已过期。如何避免它并使URL()工作?

3 个答案:

答案 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,签名有效等)