谷歌Play安全警告:不安全的TrustManager

24
在我的一个应用程序中,我使用自签名证书的HTTPS,并按照Android开发者培训网站上的示例代码进行了操作(https://developer.android.com/training/articles/security-ssl.html#UnknownCa)。
最近,我收到了以下警报,提示当前实现不安全:

安全警告

您的应用正在使用带有Apache HTTP客户端的X509TrustManager接口的不安全实现,从而存在安全漏洞。请参见此Google帮助中心文章了解详细信息,包括修复漏洞的截止日期。

是否可以提供更多详细信息,以确定除上述链接示例代码之外需要更新的内容?
如果需要,我应该实现一个自定义的TrustManager吗?如果是这样,它应该验证什么?

1
哦,这似乎已经在谷歌帮助中心文章中有所涉及:“为了正确处理SSL证书验证,请更改您的自定义X509TrustManager接口的checkServerTrusted方法中的代码,以便在服务器提供的证书不符合您的预期时引发CertificateException或IllegalArgumentException。” 您是如何设置您的TrustManager?您是如何使用它的? - CommonsWare
你所链接的页面上没有自签名服务器证书方案的代码。有未知证书颁发机构方案的代码。 - CommonsWare
@CommonsWare 我也在看这个实现自定义 TrustManager 的例子,但我不确定是否足够。http://blog.fordemobile.com/2012/04/https-requests-on-android.html(查看 EasyX509TrustManager 实现) - Muzikant
1
如果您直接使用文档中的代码,并且您的代码中没有任何implements X509TrustManager,那么可能是来自项目中的库,而不是您自己的代码。您是否使用了任何使用互联网访问的库(例如广告网络)? - CommonsWare
1
@CommonsWare 我想我找到了! 它在 mobilecore.jar 中(IronSource 广告)。 感谢您提示查看外部库。 - Muzikant
显示剩余2条评论
4个回答

15
尝试在您的代码中搜索“TrustManager”,如果没有找到,则大多数情况是因为包括了第三方库。对于我来说,这是因为使用了较旧版本的ACRA (https://github.com/ACRA/acra)。

正如在问题的评论中提到的那样,这是一个与不同的第三方库类似的情况。 - Muzikant
1
有没有办法在编译期间捕获此问题,例如使用 Lint 或任何静态分析工具? - Pavan
@Pavan - 我在 Proguard 生成的 mapping.txt 中寻找 checkServerTrusted。 - Viktor Brešan

4

对我来说,问题出在Mobilecore上。我已经从应用程序中删除了该库,并上传了新版本的apk,警告从GPlay Dev Console消失了。


3

可能有些晚了,但希望能对某些人有所帮助,在向服务器发起请求之前调用此方法。如果证书不受信任,则必须实现对话框或其他内容,以便用户可以决定如何处理,这里我使用了警报对话框。

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();
        }
    }


1

我还发现ARCA 4.3可能是我的应用程序的罪魁祸首。

问题是,有人知道如何验证问题是否已解决吗?目前,我可以访问的Play商店没有引起Google发出警告,但我们发布应用程序的其中一个合作伙伴收到了警告。在向我们的合作伙伴提供新的APK之前,我希望确认问题已解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接