2012-01-01 65 views

答えて

15

あなたは、デフォルトのトラストマネージャをラップCertificiateExpiredExceptionをキャッチし、それを無視しTrustManagerを構築する必要があります。

注: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 Sを投げます。捕まえたい/無視するものに特化してください。あなたが本当に妥当性を確認する必要があるものは、潜在的にスローされる前にチェックする必要があります。そうしないと、手動で妥当性を確認する必要があります。これよりもリラックスしたもの(特に何もしないため、例外を投げない)は、証明書の検証と検証を完全に無視します。匿名の暗号スイートを使用したり、認証を無視したりするのとほぼ同じです。これは、SSL/TLSを使用するセキュリティの目的を無効にします(期限切れに少しだけ柔軟性を持たせることとは対照的です)。

+0

このコードはまったく機能しません。 tmf.getTrustManagers()が実行されると、「TrustManagerFactoryが初期化されていません」という例外が発生します。今後投稿する前にコードをテストしてください。私はその問題を解決する方法を見つけようと1時間かけてうまく行きました。 – AndroidDev

+1

@AndroidDev、申し訳ありませんが、私は、OPがTMFを通常どおりに初期化する必要があることを知っていると仮定していましたが、おそらく正しいでしょう。 (ちょうど編集されました) – Bruno

+0

常にjavax.net.ssl.SSLHandshakeException:ピアによって接続が閉じられました –

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

セキュリティチェックを完全に無効にするコードをコピー/貼り付け/伝播することは避けてください。これは、この 'TrustManager'のように、SSL/TLSを使用する点を忘れてしまいます。 – Bruno

+0

一部のモバイルデバイスでバッテリが取り外された場合、日付は1980年のような古い日付にリセットされ、有効期限のためSSL証明書が失われます。これはあなたのアプリケーションに失敗する可能性があり、期限切れの証明書であってもアプリケーションが動作し続けることが重要な場合は、期限切れを無視することが重要です。 – AndroidDev

+0

@AndroidDevあなたの批判がBrunoのコメントに対処することを意図している場合は、任意の証明書と古くなった信頼できる証明書の受け入れには大きな違いがあることをご承知おきください。また、深刻なユーザーは、さまざまな理由で日付を調整します。 –

1

私はこの問題を解決するためにカスタムTrustManagerを作成しました。それはhttps://gist.github.com/divergentdave/9a68d820e3610513bd4fcdc4ae5f91a1にあります。このTrustManagerは、違反しているX509Certificateを別のクラスにラップして、有効期限チェックを無効にし、他のすべての検証をそのままにします。 (つまり、ホスト名に一致し、信頼できるCAにチェーンし、有効な署名など)

+0

良い例ですが、** checkValidity **メソッドのどれも呼び出されていないことを確認しました。トリガされた唯一のコールバックは** getEncoded **と** getPublicKey **でした。確かに私はローカルのキーストアを使用していて、固定された証明書がロードされているという事実と関係がありますか? – jayeffkay

+0

@jayeffkayこれをローカルで試してみましたが、いくつかのメソッドが呼び出されていました。私は 'checkValidity'が呼び出されているのを見ましたが、行番号ブレークポイントの代わりにメソッドブレークポイントを設定しなければなりませんでした。 固定された証明書が違いをもたらすかどうかはわかりませんが、動作を変更する可能性のあるサーバーの証明書(リーフ証明書ではない)として自己署名証明書を使用している場合は分かりません。 TLSサーバーのパブリックが、トラストストア内の自己署名証明書の公開キーと同じ場合、残りのチェックは問題になります。 (何が起こるかをテストしていない) – dncook

関連する問題