You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用提交Google Play被拒:HostnameVerifier不安全实现问题求助

Fixing Google Play Rejection for Unsafe HostnameVerifier in Volley

Hey there! Let's tackle this Google Play rejection issue you're facing with Volley. The problem is exactly what the rejection note says—you've got an unsafe implementation of the HostnameVerifier interface somewhere in your SSL configuration for Volley, which Google flags because it opens your app up to man-in-the-middle attacks.

Why This Happens

Chances are, in your newSslSocketFactory() method (or the code that sets up your SSL for Volley), you've got a HostnameVerifier that always returns true—something like this:

// ❌ UNSAFE: Never do this!
HostnameVerifier badVerifier = (hostname, session) -> true;

This skips all hostname validation, meaning an attacker could use a fake certificate to intercept your app's network traffic, which violates Google's security policies.

Solution 1: Use Volley's Default Configuration (No Custom SSL)

If you don't actually need custom SSL settings (like trusting self-signed certificates), the easiest fix is to use Volley's default RequestQueue without passing a custom HurlStack:

RequestQueue queue = Volley.newRequestQueue(Services.this);

Volley uses the system's default secure HostnameVerifier out of the box, so this will immediately resolve the rejection issue.

Solution 2: Custom SSL with Secure HostnameVerifier

If you do need custom SSL (e.g., trusting your own self-signed cert), you still need to keep hostname validation enabled. Here's how to set this up properly:

First, update your newSslSocketFactory() to handle your custom certificates safely:

private SSLSocketFactory newSslSocketFactory() {
    try {
        // Load your custom certificate (adjust this to match your setup)
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream certStream = getResources().openRawResource(R.raw.your_custom_cert);
        Certificate cert = cf.generateCertificate(certStream);
        certStream.close();

        // Create a KeyStore and add your certificate
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("custom_cert", cert);

        // Initialize TrustManagerFactory with your KeyStore
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);

        // Create SSLContext with your trusted managers
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        
        return sslContext.getSocketFactory();
    } catch (Exception e) {
        throw new RuntimeException("Failed to create SSLSocketFactory", e);
    }
}

Then, when creating your RequestQueue, override the HurlStack to set the system's default secure HostnameVerifier:

RequestQueue queue = Volley.newRequestQueue(Services.this, new HurlStack(null, newSslSocketFactory()) {
    @Override
    protected HttpURLConnection createConnection(URL url) throws IOException {
        HttpsURLConnection httpsConn = (HttpsURLConnection) super.createConnection(url);
        // Use the system's default verifier (strict hostname validation)
        httpsConn.setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier());
        return httpsConn;
    }
});

Key Takeaway

Never skip hostname validation. The HostnameVerifier's job is to ensure that the server your app is connecting to is actually the one it claims to be. Using the system's default verifier ensures this check is done properly, keeping your users' data safe and complying with Google Play's policies.

内容的提问来源于stack exchange,提问作者rogerio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:28:31