【问题标题】:Google Play Alert- App using unsafe implementation of the hostnameVerifierGoogle Play 警报 - 应用程序使用不安全的 hostnameVerifier 实现
【发布时间】:2020-01-14 12:00:03
【问题描述】:

当我将 APK 上传到下面的 Play 商店时,我收到了来自 google play 的安全警报。 您的应用正在使用 HostnameVerifier 接口的不安全实现。 我的代码在这里。

public class NukeSSLCerts {
    protected static final String TAG = "NukeSSLCerts";

    public static void nuke() {
        try {
            TrustManager[] trustManagerArr = new TrustManager[]{new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] x509CertificateArr, String str) {
                }

                public void checkServerTrusted(X509Certificate[] x509CertificateArr, String str) {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            }};
            SSLContext instance = SSLContext.getInstance("SSL");
            instance.init(null, trustManagerArr, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(instance.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                public  boolean verify(String str, SSLSession sSLSession) {
                    return true;

                }
            });
        } catch (Exception unused) {
        }
    }
}

【问题讨论】:

    标签: android android-studio


    【解决方案1】:

    接受所有 SSL 证书通常不是理想的情况。稍微好一点的是只接受使用此代码 sn-p 的特定 SSL 证书。

     final class CustomTrust {
    
    
    
       private static InputStream trustedCertificatesInputStream() {
        String certificate_one = "ADD_YOUR_CERTIFICATE";
        String certificate_two = "ADD_YOUR_CERTIFICATE";
    
        return new Buffer()
                .writeUtf8(certificate_one)
                .writeUtf8(certificate_two)
                .inputStream();
         }
    
          public static X509TrustManager getTrustManagerForCertificates()
            throws GeneralSecurityException {
    
        InputStream in= trustedCertificatesInputStream();
        CertificateFactory certificateFactory = 
        CertificateFactory.getInstance("X.509");
        Collection<? extends Certificate> certificates = 
        certificateFactory.generateCertificates(in);
        if (certificates.isEmpty()) {
            throw new IllegalArgumentException("expected non-empty set of trusted 
        certificates");
        }
    
        // Put the certificates a key store.
        char[] password = "password".toCharArray(); // Any password will work.
        KeyStore keyStore = newEmptyKeyStore(password);
        int index = 0;
        for (Certificate certificate : certificates) {
            String certificateAlias = Integer.toString(index++);
            keyStore.setCertificateEntry(certificateAlias, certificate);
        }
    
        // Use it to build an X509 trust manager.
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
                KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, password);
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
        if (trustManagers.length != 1 || !(trustManagers[0] instanceof 
         X509TrustManager)) {
            throw new IllegalStateException("Unexpected default trust managers:"
                    + Arrays.toString(trustManagers));
        }
        return (X509TrustManager) trustManagers[0];
    }
    
    private static KeyStore newEmptyKeyStore(char[] password) throws 
         GeneralSecurityException {
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            InputStream in = null; // By convention, 'null' creates an empty key 
             store.
            keyStore.load(in, password);
            return keyStore;
        } catch (IOException e) {
            throw new AssertionError(e);
        }
    }}
    

    在你的 OKHttp 客户端中使用这个 CustomTrust。

      public class MyOkHttpClient {
      public static OkHttpClient get(Context context) {
        try {
    
            // Install the all-trusting trust manager
    
    
        X509TrustManager trustManager = 
       CustomTrust.getTrustManagerForCertificates();
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{trustManager}, null);
            SSLSocketFactory sslSocketFactory = 
          sslContext.getSocketFactory();
    
            OkHttpClient.Builder okHttpBuilder = new 
             OkHttpClient.Builder()
    
                    .sslSocketFactory(sslSocketFactory, trustManager)
    
                    .hostnameVerifier((hostname, session) -> true)
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
    
    
            return okHttpBuilder.build();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    } }
    

    【讨论】:

    • 这种安全措施是否得到 Google 的认可?
    • @HenriquedeSousa 目前我正在关注此链接并搜索谷歌批准的有效答案。同时,如果您有其他正宗的解决方案,请与我们分享。 futurestud.io/tutorials/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多