2016-10-31 20 views
1

セキュリティスキャンプログラムの結果から、私はアプリの信頼する認証局を制限する必要があります。WebView loadUrl()の信頼性認証局

スキャン結果は、webView.loadUrl("https://example.com/page");の行を指しています。私は自分のTrustManagerを使用するSslSocketFactoryをどのように作成できるかを見ていますが、私はWebViewにそれを設定できるAPIは表示されません。

https://developer.android.com/training/articles/security-ssl.html#UnknownCa

これを達成するためのいくつかの可能な方法は何ですか?

+0

報告する問題の解決方法の詳細が記載されていない「セキュリティスキャンプログラム」は避けてください。 – CommonsWare

+0

@CommonsWareレポートの「お勧め」セクションは、上記のリンクのコードスニペットとまったく同じで、証明書ピン割り当てまたはカスタムキーストアを使用することを推奨します。これ以外の情報はありません。 – GreenTeaIterator

+0

AFAIK、どちらも 'WebView'では使用できません。 – CommonsWare

答えて

2

私はWebViewClientonReceivedSslErrorメソッドは良いエントリポイントになると思います。

まず、https://developer.android.com/training/articles/security-ssl.html#UnknownCaのまったく同じスニペットにしたがって、TrustManagerを準備します。

TrustManagerFactory tmf = null; 

    private void initTrustStore() throws 
      java.security.cert.CertificateException, FileNotFoundException, 
      IOException, KeyStoreException, NoSuchAlgorithmException { 

     // Create a KeyStore containing our trusted CAs 
     String keyStoreType = KeyStore.getDefaultType(); 
     KeyStore trustedKeyStore = KeyStore.getInstance(keyStoreType); 
     trustedKeyStore.load(null, null); 

     CertificateFactory cf = CertificateFactory.getInstance("X.509"); 

     InputStream caInput = new BufferedInputStream(
        getResources().getAssets().open("ca.crt")); 
      Certificate ca; 
      try { 
       ca = cf.generateCertificate(caInput); 
       Log.d(TAG, "ca-root DN=" + ((X509Certificate) ca).getSubjectDN()); 
      } 
      finally { 
       caInput.close(); 
      } 
      trustedKeyStore.setCertificateEntry("ca", ca); 

     // Create a TrustManager that trusts the CAs in our KeyStore 
     String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
     tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
     tmf.init(trustedKeyStore); 

    } 

続いて、最後にhttps://stackoverflow.com/a/6379434/1099884

private class CheckServerTrustedWebViewClient extends WebViewClient{ 
    public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) { 
     Log.d(TAG, "onReceivedSslError"); 
     boolean passVerify = false; 

     if(error.getPrimaryError() == SslError.SSL_UNTRUSTED){ 
      SslCertificate cert = error.getCertificate(); 
      String subjectDN = cert.getIssuedTo().getDName(); 
      Log.d(TAG, "subjectDN: "+subjectDN); 
      try{ 
       Field f = cert.getClass().getDeclaredField("mX509Certificate"); 
       f.setAccessible(true); 
       X509Certificate x509 = (X509Certificate)f.get(cert); 

       X509Certificate[] chain = {x509}; 
       for (TrustManager trustManager: tmf.getTrustManagers()) { 
        if (trustManager instanceof X509TrustManager) { 
         X509TrustManager x509TrustManager = (X509TrustManager)trustManager; 
         try{ 
          x509TrustManager.checkServerTrusted(chain, "generic"); 
          passVerify = true;break; 
         }catch(Exception e){ 
          Log.e(TAG, "verify trustManager failed", e); 
          passVerify = false; 
         } 
        } 
       } 
       Log.d(TAG, "passVerify: "+passVerify); 
      }catch(Exception e){ 
       Log.e(TAG, "verify cert fail", e); 
      } 
     } 
     if(passVerify == true)handler.proceed(); 
     else handler.cancel(); 

    }  

} 

からスニペットをチェックし、カスタムWebViewClientクラスを拡張し、一つの問題がある、しかしCheckServerTrustedWebViewClientWebView

webView.setWebViewClient(new CheckServerTrustedWebViewClient()); 

を設定します。準備されたCA証明書は、サーバー証明書とまったく同じです(中間CA NOTルートCA)。ルートCA証明書のみを提供することはできません。 TrustManagerは実行時にサーバー証明書チェーンをダウンロードできませんか?なにか提案を?

関連する問題