首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >X509TrustManager - Google界面的不安全实现

X509TrustManager - Google界面的不安全实现
EN

Stack Overflow用户
提问于 2020-10-13 07:47:59
回答 2查看 2.3K关注 0票数 2

当我试图上传一个应用程序到google play时,我会收到一条消息。“接口x509trustmanager的不安全实现”。在Google Play的一条信息中,它说:

为了避免验证SSL证书时出现问题,请更改

接口中的checkServerTrusted方法的代码,以便在检测到可疑证书时抛出CertificateException或IllegalArgumentException。

我找到的所有选项都使用checkValidity方法来验证证书,但是Google还添加了:

不使用checkValidity验证服务器的证书。此方法检查证书的有效性,而不是其安全性。

如何正确地更改checkServerTrusted方法的代码?我当前实现的x509TrustManager:

代码语言:javascript
复制
X509TrustManager trustManager = new X509TrustManager() {
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            X509Certificate[] cArrr = new X509Certificate[0];
            return cArrr;
        }

        @Override
        public void checkServerTrusted(final X509Certificate[] chain,
                                       final String authType) throws CertificateException {
            try {
                chain[0].checkValidity();
            } catch (Exception e) {
                throw new CertificateException("Certificate not valid or trusted.");
            }
        }

        @Override
        public void checkClientTrusted(final X509Certificate[] chain,
                                       final String authType) throws CertificateException {
        }
    };
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-13 15:00:07

我以这种方式更改了X509TrustManager实现,该应用程序通过了Google验证:

代码语言:javascript
复制
TrustManager[] victimizedManager = new TrustManager[]{

                new X509TrustManager() {

                    public X509Certificate[] getAcceptedIssuers() {

                        X509Certificate[] myTrustedAnchors = new X509Certificate[0];

                        return myTrustedAnchors;
                    }

                    @Override
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        if(chain == null || chain.length == 0)throw new IllegalArgumentException("Certificate is null or empty");
                        if(authType == null || authType.length() == 0) throw new IllegalArgumentException("Authtype is null or empty");
                        if(!authType.equalsIgnoreCase("ECDHE_RSA") &&
                                !authType.equalsIgnoreCase("ECDHE_ECDSA") &&
                                !authType.equalsIgnoreCase("RSA") &&
                                !authType.equalsIgnoreCase("ECDSA")) throw new CertificateException("Certificate is not trust");
                        try {
                            chain[0].checkValidity();
                        } catch (Exception e) {
                            throw new CertificateException("Certificate is not valid or trusted");
                        }
                    }
                }
        };
票数 2
EN

Stack Overflow用户

发布于 2020-10-13 08:41:58

我以前也犯过这个错误。在我的例子中,这就是解决它的方法:

代码语言:javascript
复制
private boolean isVerified;

@SuppressLint("TrulyRandom")
public static void handleSSLHandshake() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }

            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        }};

        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(final String host, final SSLSession session) {
                System.out.print("host" + host+ "\n");
                isVerified = host.equalsIgnoreCase(Constants.hostNameVerifierString)
                        || host.contains("google") || host.contains("gstatic");

                System.out.print(isVerified);
                return isVerified;
            }
        });
    } catch (Exception ignored) {
    }
}

在有网络调用的活动中,可以调用handleSSLHandshake()方法。或者,如果您使用Dagger或任何依赖项注入库,您应该能够将它注入到您想要创建的网络调用的任何位置。

Constants.hostNameVerifierString是我在网络调用中使用的URL,添加" google“和"gstatic”是因为我也在使用google地图。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64330843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档