HostnameVerifier 接口的不安全实现 - Android

Unsafe implementation of the HostnameVerifier interface - Android

应用在 Play 商店被拒绝的原因:

Your app(s) are using an unsafe implementation of the HostnameVerifier interface. You can find more information about how to resolve the issue in this Google Help Center article.

大家好,

当我将应用程序上传到 Play 商店时,google Play 控制台出现 HostnameVerifier 问题。我已经尝试了我在 Whosebug 上找到的每一个解决方案,但问题仍然是一样的,即 您的应用程序正在使用 HostnameVerifier 接口的不安全实现。

此外,我已经通过 google documentation 解决了这个问题,但没有成功。有人对此有解决方案吗?感谢您的帮助

下面是我的ServiceGeneratorclass

public class ServiceGenerator {

    private static final String KEY_AUTH_HEADER = "Authorization";
    private Context context;
    private Retrofit.Builder builder;
    private OkHttpClient.Builder httpClient;
    HandshakeCertificates certificates;

    ServiceGenerator(Context context) {
        this.context = context;
        final String dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";

        httpClient = new OkHttpClient.Builder();

        certificates = new HandshakeCertificates.Builder()
                .addTrustedCertificate(AppConstants.SSL_CERTIFICATE_DEMO)
                .addTrustedCertificate(AppConstants.SSL_CERTIFICATE_LIVE)
                // Uncomment if standard certificates are also required.
                .addPlatformTrustedCertificates()
                .build();

        // Install the all-trusting trust manager
        final SSLContext sslContext;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new X509TrustManager[]{certificates.trustManager()}, new java.security.SecureRandom());

            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            httpClient.sslSocketFactory(sslSocketFactory, certificates.trustManager());
            httpClient.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
       
        httpClient.connectTimeout(60, TimeUnit.SECONDS);
        httpClient.readTimeout(60, TimeUnit.SECONDS);
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();

        int cacheSize = 20 * 1024 * 1024; // 20 MB
        Cache cache = new Cache(context.getCacheDir(), cacheSize);

        logging.level(HttpLoggingInterceptor.Level.BASIC);

        httpClient.cache(cache);
        httpClient.addNetworkInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Response originalResponse = chain.proceed(chain.request());
                if (Functions.isConnected(context)) {
                    int maxAge = 60 * 2; // read from cache for 2 minute
                    return originalResponse.newBuilder()
                            .header("Cache-Control", "public, max-age=" + maxAge)
                            .build();
                } else {
                    int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
                    return originalResponse.newBuilder()
                            .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                            .build();
                }
            }
        });

        httpClient.addInterceptor(logging);
        httpClient.addInterceptor(new HeaderInterceptor());

        Gson gson = new GsonBuilder()
                .setDateFormat(dateFormat)
                .create();
        builder = new Retrofit.Builder()
                .baseUrl(Apis.HOST);

        builder.addConverterFactory(GsonConverterFactory.create(gson));
    }

    class HeaderInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {

            String authKey = "authKey";
            if (PrefUtils.isUserLoggedIn(context) && PrefUtils.getUserFullProfileDetails(context) != null) {
                authKey = PrefUtils.getUserFullProfileDetails(context).getAuthKey();
            }

            Request newRequest = chain.request().newBuilder()
                    .addHeader("auth-key", authKey)
                    .build();
            return chain.proceed(newRequest);
        }
    }

    public <S> S createService(Class<S> serviceClass) {
        Retrofit retrofit = builder.client(httpClient.build()).build();
        return retrofit.create(serviceClass);
    }
}

实际上,这个问题是由于 Braintree SDK 使用了 HostnamVerifier。我已经为 Braintree 解决了这个 GitHub 问题 channel 并且知道他们已经解决了这个问题,我只需要更新 SDK 版本并再次将捆绑包上传到 Play 商店。这解决了我的问题并能够将我的应用程序上传到 Play 商店。

任何仍在寻找更好的解决方案但无法在任何地方找到它的人,请仔细阅读此 link 并在那里提交您的问题详细信息,也请让他们提及导致此问题的文件。他们会在邮件中回复您文件名。