【问题标题】:App rejected by Google Play应用被 Google Play 拒绝
【发布时间】:2017-07-07 19:37:30
【问题描述】:

我正在开发一个包含社交网络登录的 Android 应用程序。 在这个问题之后,我删除了包含“WebViewClient.onReceivedSslError”的类。 但是当我在 Google Play 商店中上传应用程序时,它被拒绝并出现以下错误。

“如何解决应用中的 WebView SSL 错误处理程序警报。”

我也在使用该类在没有 Intent 的情况下在后台发送邮件。 这使用“SSL”和“TrustManagerFactory.X509”。请问这是拒绝的理由吗? 我想如果这是拒绝的原因,那么我可能会收到其他错误,例如“ 由于 X509TrustManager 的实施不安全,应用被 Google Play 商店拒绝。

寻求支持。提前致谢。


这是我从 Google Play 收到的消息。

Google Play 开发者您好,

我们拒绝了 VISApp,包名称为 com.avonmobility.visapp,因为它违反了我们的恶意行为或用户数据政策。如果您提交了更新,您之前的应用版本仍可在 Google Play 上找到。

此应用使用的软件包含对用户的安全漏洞,或允许在未经适当披露的情况下收集用户数据。

以下是在您最近提交的文件中检测到的问题和相应 APK 版本的列表。请尽快升级您的应用并增加升级后 APK 的版本号。

漏洞 APK 版本 SSL 错误处理程序 有关如何解决 WebView SSL 错误处理程序警报的更多信息,请参阅此 Google 帮助中心文章。

15 要确认您已正确升级,请将应用的更新版本提交到开发者控制台,并在 5 小时后回来查看以确保警告已消失。

虽然这些漏洞可能不会影响使用该软件的所有应用,但最好及时更新所有安全补丁。确保更新应用中存在已知安全问题的所有库,即使您不确定这些问题是否与您的应用相关。

应用还必须遵守开发者分发协议和开发者计划政策。

如果您认为我们做出此决定有误,请联系我们的开发人员支持团队。

最好的,

Google Play 团队

【问题讨论】:

  • 您是否使用任何没有有效 SSL 证书的后端(服务器端)。如果不是,那么我猜您正在使用 X509TrustManager 来忽略无效的 SSL 证书错误。这是谷歌不能接受的。所以我建议你为你的服务器端获取一个有效的 SSL 证书。
  • @AkhilSoman 嗨 Akhil,谢谢回复。哥们我也有同感。但我不知道如何实现它。你能指导我吗?
  • 我问了一个朋友,他给了我这个链接:howto-expert.com/…

标签: android ssl


【解决方案1】:

对我来说同样的问题在你的项目中添加这个创建一个类。

                  import org.apache.http.HttpVersion;
       import org.apache.http.conn.ClientConnectionManager;
        import org.apache.http.conn.scheme.PlainSocketFactory;
        import org.apache.http.conn.scheme.Scheme;
       import org.apache.http.conn.scheme.SchemeRegistry;
     import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
        import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
      import org.apache.http.params.BasicHttpParams;
                                import org.apache.http.params.HttpParams;
    import org.apache.http.params.HttpProtocolParams;
       import org.apache.http.protocol.HTTP;

          import java.io.BufferedInputStream;
     import java.io.IOException;
      import java.io.InputStream;
     import java.net.Socket;
     import java.security.KeyManagementException;
     import java.security.KeyStore;
   import java.security.KeyStoreException;
   import java.security.NoSuchAlgorithmException;
   import java.security.UnrecoverableKeyException;
     import java.security.cert.Certificate;
       import java.security.cert.CertificateException;
     import java.security.cert.CertificateFactory;
       import java.security.cert.X509Certificate;

        import javax.net.ssl.HttpsURLConnection;
         import javax.net.ssl.SSLContext;
     import javax.net.ssl.TrustManager;
     import javax.net.ssl.X509TrustManager;


       public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");


public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
    super(truststore);

    X509TrustManager tm = new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    };

    sslContext.init(null, new TrustManager[]{tm}, null);
}

@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
    return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}

@Override
public Socket createSocket() throws IOException {
    return sslContext.getSocketFactory().createSocket();
}

/**
 * Makes HttpsURLConnection trusts a set of certificates specified by the KeyStore
 */
public void fixHttpsURLConnection() {
    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
}

/**
 * Gets a KeyStore containing the Certificate
 *
 * @param cert InputStream of the Certificate
 * @return KeyStore
 */
public static KeyStore getKeystoreOfCA(InputStream cert) {

    // Load CAs from an InputStream
    InputStream caInput = null;
    Certificate ca = null;
    try {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        caInput = new BufferedInputStream(cert);
        ca = cf.generateCertificate(caInput);
    } catch (CertificateException e1) {
        e1.printStackTrace();
    } finally {
        try {
            if (caInput != null) {
                caInput.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Create a KeyStore containing our trusted CAs
    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = null;
    try {
        keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return keyStore;
}

/**
 * Gets a Default KeyStore
 *
 * @return KeyStore
 */
public static KeyStore getKeystore() {
    KeyStore trustStore = null;
    try {
        trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);
    } catch (Throwable t) {
        t.printStackTrace();
    }
    return trustStore;
}

/**
 * Returns a SSlSocketFactory which trusts all certificates
 *
 * @return SSLSocketFactory
 */
public static SSLSocketFactory getFixedSocketFactory() {
    SSLSocketFactory socketFactory;
    try {
        socketFactory = new MySSLSocketFactory(getKeystore());
        socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    } catch (Throwable t) {
        t.printStackTrace();
        socketFactory = SSLSocketFactory.getSocketFactory();
    }
    return socketFactory;
}

/**
 * Gets a DefaultHttpClient which trusts a set of certificates specified by the KeyStore
 *
 * @param keyStore custom provided KeyStore instance
 * @return DefaultHttpClient
 */
public static DefaultHttpClient getNewHttpClient(KeyStore keyStore) {

    try {
        SSLSocketFactory sf = new MySSLSocketFactory(keyStore);
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

}

【讨论】:

  • 嗨,谢谢你的回复。你能解释一下在哪里使用它并调用它吗?
  • 新建一个类
  • 在谷歌搜索你会在发送 json 时得到我的调用
【解决方案2】:

解决 Google Play 警告:WebViewClient.onReceivedSslError 处理程序

不总是强制 handler.proceed();但你还必须包括 handler.cancel();这样用户就可以避免加载 unsaif 内容。

处理 WebViewClient.onReceivedSslError 处理程序的不安全实现

使用下面的代码

 webView.setWebViewClient(new SSLTolerentWebViewClient());
 webView.loadUrl(myhttps url);

 private class SSLTolerentWebViewClient extends WebViewClient {
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {

    AlertDialog.Builder builder = new AlertDialog.Builder(Tab1Activity.this);
    AlertDialog alertDialog = builder.create();
    String message = "SSL Certificate error.";
    switch (error.getPrimaryError()) {
        case SslError.SSL_UNTRUSTED:
            message = "The certificate authority is not trusted.";
            break;
        case SslError.SSL_EXPIRED:
            message = "The certificate has expired.";
            break;
        case SslError.SSL_IDMISMATCH:
            message = "The certificate Hostname mismatch.";
            break;
        case SslError.SSL_NOTYETVALID:
            message = "The certificate is not yet valid.";
            break;
    }

    message += " Do you want to continue anyway?";
    alertDialog.setTitle("SSL Certificate Error");
    alertDialog.setMessage(message);
    alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            // Ignore SSL certificate errors
            handler.proceed();
        }
    });

    alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {

            handler.cancel();
        }
    });
    alertDialog.show();
}
}

您必须提醒用户使用 SSL,以便 Google 允许您的应用执行此操作

【讨论】:

  • 嗨,Ajay,谢谢回复。我没有在我的代码中使用 Webview。但我不知道为什么会这样。哥们还有什么其他原因?
【解决方案3】:
I also had SSLCertification issue at the time uploading singed apk.
you have to return true for all your trusted http hosts including 3rd party libraries http.

我在这里说明我是如何解决这个问题的,抱歉,我没有提供链接的原始路径,这些 Link 对我有帮助。

     TrustManager[] trustAllCerts = 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[] 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 hostname, SSLSession arg1) {
                if (hostname.equalsIgnoreCase("demo.mysite.com") ||
                        hostname.equalsIgnoreCase("prod.mysite.com") ||
                        hostname.equalsIgnoreCase("22.2.202.22:3333") ||
                        hostname.equalsIgnoreCase("cloud.cloudDeveSite.net") ||                            
                        hostname.equalsIgnoreCase("11.2.222.22:2222") ||
                        hostname.equalsIgnoreCase("multispidr.3rdPartyLibrary.io")) {
                    return true;
                } else {
                    return false;
                }
            }
        });

提到所有有 SSLCertification 问题的 api,你还必须提到 3rd 方 api,当你运行该代码时,你会得到那些错误的 HTTP 链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 2017-01-28
    • 2019-04-06
    • 2016-08-09
    • 1970-01-01
    相关资源
    最近更新 更多