簡體   English   中英

接口 X509TrustManager 的不安全實現 - Google Play

[英]Unsafe implementation of the interface X509TrustManager - Google Play

當我嘗試將應用程序上傳到 google play 時,我收到一條消息。 “接口 x509trustmanager 的不安全實現”。 在來自 Google Play 的消息中,它說:

為避免驗證SSL證書時出現問題,修改X509TrustManager接口中checkServerTrusted方法的代碼,當檢測到可疑證書時拋出CertificateException或IllegalArgumentException。

我發現的所有選項都使用 checkValidity 方法來驗證證書,但 Google 還添加了:

不要使用 checkValidity 來驗證服務器的證書。 此方法檢查證書的有效性,而不是其安全性。

如何正確更改 checkServerTrusted 方法的代碼? 我當前的 x509TrustManager 實現:

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 {
        }
    };

我以這種方式更改了 X509TrustManager 實現,並且該應用程序通過了 Google Play 驗證:

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

我以前有過這個錯誤。 就我而言,這是修復它的原因:

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”是因為我也在使用谷歌地圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM