2016-02-17 59 views
21

在我的一個應用程序中,我使用HTTPS和自簽名證書,並遵循Android開發人員培訓網站(https://developer.android.com/training/articles/security-ssl.html#UnknownCa)的示例代碼。谷歌播放安全警報不安全的TrustManager

我最近買了以下警告說,目前的實現並不保證:

安全警報

您的應用使用不安全的實現與Apache HTTP客戶端 X509TrustManager接口,導致一個 安全漏洞。有關詳細信息,請參閱this Google Help Center article,其中包括修復漏洞的截止日期。

有人可以提供更多的細節,應該在上面鏈接的示例代碼之外進行更新嗎?

我應該實施自定義TrustManager嗎?如果是這樣,它應該驗證什麼?

+1

嗯,這似乎[谷歌的幫助中心文章在被覆蓋(https://support.google.com/faqs/answer/6346016):「要正確處理SSL證書驗證,請在自定義X509TrustManager接口的checkServerTrusted方法中更改您的代碼,以便在服務器提供的證書不符合您的期望時引發CertificateException或IllegalArgumentException。你究竟如何設置你的TrustManager?你怎麼使用它? – CommonsWare

+0

@CommonsWare與示例代碼完全相同https://developer.android.com/training/articles/security-ssl.html#UnknownCa 我應該做什麼不同嗎? – Muzikant

+0

在鏈接到的頁面上,沒有用於自簽名服務器證書方案的代碼。未知證書權限方案有代碼。 – CommonsWare

回答

3

對我來說問題是Mobilecore。我已經從應用中移除了該庫並上傳了新版本的apk,並且該警告已從GPlay Dev Console中消失。

14

嘗試在您的代碼中搜索「TrustManager」,如果找不到任何內容,則大多數情況下都是因爲包含第三方庫。

對我而言,這是因爲使用舊版本的ACRA(https://github.com/ACRA/acra)。

+0

正如問題的評論中所述,這是一個與第三方庫不同的類似案例 – Muzikant

+1

有沒有什麼方法可以在編譯期間像使用Lint或任何靜態分析工具一樣捕獲此問題。 – Pavan

+0

關於ACRA,請參閱https://github.com/ACRA/acra/issues/374 – mhsmith

1

我還發現,ARCA 4.3似乎可能是我的應用程序的罪魁禍首。

問題,有誰知道驗證問題解決?目前,我可以訪問的Play商店不會導致Google向我發出警告,但我們發佈應用的合作伙伴之一已收到警告。我想在向我們的合作伙伴提供新APK之前驗證問題是否已解決。

2

可能會遲到,但希望它可以幫助某人,在請求到服務器之前調用此方法。如果證書不信任,你有實現對話框或東西,所以用戶可以決定,在這裏我使用警報對話框。

public static void trustSSLCertificate(final Activity mActivity, final DownloadPortalTask task){ 
 
     try { 
 
      HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { 
 
       public boolean verify(String hostname, SSLSession session) { 
 
        return true; 
 
       } 
 
      }); 
 

 
      SSLContext context = SSLContext.getInstance("TLS"); 
 
      context.init(null, new X509TrustManager[]{new X509TrustManager() { 
 
       public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
 
       } 
 

 
       public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
 
        try { 
 
         chain[0].checkValidity(); 
 
        } catch (final Exception e) { 
 

 
         mActivity.runOnUiThread(new Runnable() { 
 
          @Override 
 
          public void run() { 
 
           AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); 
 
           AlertDialog alertDialog = builder.create(); 
 
           alertDialog.setCancelable(false); 
 
           String message = "There a problem with the security certificate for this web site."; 
 
           message += "\nDo you want to continue anyway?"; 
 
           alertDialog.setTitle("SSL Certificate Error"); 
 
           alertDialog.setMessage(message); 
 
           alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { 
 
            @Override 
 
            public void onClick(DialogInterface dialog, int which) { 
 
             acceptSSL = true; 
 
             return; 
 

 
            } 
 
           }); 
 

 
           alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() { 
 
            @Override 
 
            public void onClick(DialogInterface dialog, int which) { 
 
             acceptSSL = true; 
 
             task.onInterruptedDownload(); 
 
            } 
 
           }); 
 
           alertDialog.show(); 
 

 
          } 
 

 
         }); 
 

 
         while(!acceptSSL){ 
 
          try{ 
 
           Thread.sleep(1000); 
 
          } catch(InterruptedException er) { } 
 
         } 
 

 
        } 
 
       } 
 
       public X509Certificate[] getAcceptedIssuers() { 
 
        return new X509Certificate[0]; 
 
       } 
 
      }}, new SecureRandom()); 
 
      HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); 
 
     } catch (Exception e) { // should never happen 
 
      e.printStackTrace(); 
 
     } 
 
    }