如何修复HostnameVerifier的不安全实现

时间:2019-08-04 22:44:43

标签: android

我已从Playstore收到此警告,因为下面的代码正在接受所有主机

  

您的应用正在使用HostnameVerifier的不安全实现。并指向Google Play帮助中心文章的链接,以获取有关漏洞修复和期限的详细信息。

@SuppressLint("TrulyRandom")
private 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("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                Log.i("hostname",""+arg0);
                return true;
            }
        });



    } catch (Exception ignored) {
    }
}

现在的问题是,除了主要主机之外,我不知道需要添加多少主机。

当我尝试读取应用程序中使用的主机时,我发现它们很多而且来自库(Google广告,applovin,crashlytics,onesignal ...)

以下是示例:

  

主机名:marcoasensiomadrid.website

     

主机名:api.crashlytics.com

     

主机名:ms.applovin.com

     

主机名:d.applovin.com

     

主机名:d.applovin.com

     

主机名:rt.applovin.com

     

主机名:a.applovin.com

     

主机名:googleads.g.doubleclick.net

     

主机名:res1.applovin.com

     

主机名:onesignal.com

     

主机名:pagead2.googleadservices.com

     

主机名:onesignal.com

     

主机名:api.crashlytics.com

     

主机名:ms.applovin.com

     

主机名:d.applovin.com

     

主机名:d.applovin.com

     

主机名:rt.applovin.com

     

主机名:a.applovin.com

     

主机名:googleads.g.doubleclick.net

     

主机名:res1.applovin.com

     

主机名:onesignal.com

     

主机名:pagead2.googleadservices.com

     

主机名:googleads.g.doubleclick.net

     

主机名:googleads.g.doubleclick.net

     

主机名:prod-a.applovin.com

     

主机名:track.tenjin.io

     

主机名:play.google.com

     

主机名:play.google.com

     

主机名:a.applovin.com

     

主机名:res1.applovin.com

     

主机名:res1.applovin.com

     

主机名:res1.applovin.com

     

主机名:pagead2.googleadservices.com

     

主机名:pagead2.googleadservices.com

如何允许我的应用使用所有主机并同时通过警告?

1 个答案:

答案 0 :(得分:0)

您的自定义验证程序仅适用于通过 HttpsURLConnection 建立的 ssl 连接;大多数第三方库将不涉及。无论如何,您的问题似乎是您需要允许某些未经默认验证的主机,反之亦然。在这种情况下,以下代码可能会有所帮助:

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
  private final HostnameVerifier systemHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
  private final String hostWithSpecialCertificate = "marcoasensiomadrid.website";

  @Override
  public boolean verify(String hostname, SSLSession session) {
    if (hostWithSpecialCertificate.equalsIgnoreCase(hostname)) {
      X509Certificate certificate = (X509Certificate)(session.getPeerCertificates()[0]);
      final int ALT_DNS_NAME = 2;
      for (String altName : getSubjectAltNames(certificate, ALT_DNS_NAME)) {
        if (systemHostnameVerifier.verify(altName, session)) return true;
      }
      X500Principal principal = certificate.getSubjectX500Principal();
      return systemHostnameVerifier.verify(new DistinguishedNameParser(principal).findMostSpecific("cn"), session);
    }
    return systemHostnameVerifier.verify(hostname, session);
  }
});

这使用 private List<String> getSubjectAltNames(X509Certificate certificate, int type)(从 OkHostnameVerifier.java 逐字复制)。