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

Android Studio中javax.net.ssl.SSLHandshakeException异常求助

SSL握手失败:Android Volley调用InfinityFree部署的REST API报错

我为应用创建了REST API,部署在InfinityFree平台连接MySQL数据库,网站已配置从InfinityFree获取的SSL证书。但在Android Studio项目中用Volley库调用该API时,出现如下错误,之前在000webhost部署时一切正常,请问问题出在哪里?

D/Linux: [Posix_connect Debug]Process com.abiapp.androidukk :443 
W/System.err: com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
W/System.err:     at com.android.volley.toolbox.NetworkUtility.shouldRetryException(NetworkUtility.java:173)
W/System.err:     at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:145)
W/System.err:     at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:132)
W/System.err:     at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:111)
W/System.err:     at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:90)
W/System.err: Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
W/System.err:     at com.android.org.conscrypt.SSLUtils.toSSLHandshakeException(SSLUtils.java:362)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.convertException(ConscryptEngine.java:1134)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1089)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:876)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:849)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.access$100(ConscryptEngineSocket.java:722)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:238)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:217)
W/System.err:     at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:196)
W/System.err:     at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:153)
W/System.err:     at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:262)
W/System.err:     at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:219)
W/System.err:     at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:30)
W/System.err:     at com.android.volley.toolbox.HurlStack.createOutputStream(HurlStack.java:319)
W/System.err:     at com.android.volley.toolbox.HurlStack.addBody(HurlStack.java:301)
W/System.err:     at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:285)
W/System.err:     at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:257)
W/System.err:     at com.android.volley.toolbox.HurlStack.executeRequest(HurlStack.java:89)
W/System.err:     at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:104)
W/System.err:   ... 3 more
W/System.err: Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:661)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:510)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:428)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:356)
W/System.err:     at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
W/System.err:     at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:90)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket$2.checkServerTrusted(ConscryptEngineSocket.java:161)
W/System.err:     at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:250)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.verifyCertificateChain(ConscryptEngine.java:1644)
W/System.err:     at com.android.org.conscrypt.NativeCrypto.ENGINE_SSL_read_direct(Native Method)
W/System.err:     at com.android.org.conscrypt.NativeSsl.readDirectByteBuffer(NativeSsl.java:568)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataDirect(ConscryptEngine.java:1095)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1079)
W/System.err:   ... 29 more
W/System.err: Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
W/System.err:   ... 42 more
I/InputTransport: Create ARC handle: 0x78a4e05920
D/ViewRootImpl[StartActivity]: msg2 update new insets InsetsState: {mDisplayFrame=Rect(0, 0 - 1080, 2340), mSources= { InsetsSource: {mType=ITYPE_STATUS_BAR, mFrame=[0,0][1080,96], mVisible=true}, InsetsSource: {mType=ITYPE_TOP_GESTURES, mFrame=[0,0][1080,96], mVisible=true}, InsetsSource: {mType=ITYPE_LEFT_GESTURES, mFrame=[0,0][0,0], mVisible=true}, InsetsSource: {mType=ITYPE_RIGHT_GESTURES, mFrame=[0,0][0,0], mVisible=true}, InsetsSource: {mType=ITYPE_TOP_TAPPABLE_ELEMENT, mFrame=[0,0][1080,96], mVisible=true}, InsetsSource: {mType=ITYPE_LEFT_DISPLAY_CUTOUT, mFrame=[0,0][-2147483648,2340], mVisible=true}, InsetsSource: {mType=ITYPE_TOP_DISPLAY_CUTOUT, mFrame=[0,0][1080,96], mVisible=true}, InsetsSource: {mType=ITYPE_RIGHT_DISPLAY_CUTOUT, mFrame=[2147483647,0][1080,2340], mVisible=true}, InsetsSource: {mType=ITYPE_BOTTOM_DISPLAY_CUTOUT, mFrame=[0,2147483647][1080,2340], mVisible=true}, InsetsSource: {mType=ITYPE_IME, mFrame=[0,0][0,0], mVisible=false}, InsetsSource: {mType=ITYPE_SEC_IME, mFrame=[0,0][0,0], mVisible=false} }

问题原因

核心错误Trust anchor for certification path not found说明:Android系统无法识别InfinityFree提供的SSL证书的根信任机构,或者证书链配置不完整。

000webhost的证书由Android系统默认信任的CA机构签发,所以之前调用正常;而InfinityFree的证书要么是由不被Android默认信任的CA签发,要么部署时只配置了服务器证书,缺少中间证书或根证书,导致系统无法验证证书的合法性。


解决方法

1. 检查并修复InfinityFree的证书链配置

  • 登录InfinityFree后台,确认下载的证书包包含完整链文件(通常包括服务器证书、中间证书、根证书)
  • 重新部署证书时,将所有链文件上传并配置到服务器,不要只上传服务器证书

2. 在Android项目中添加自定义信任证书

如果证书链配置正确但Android仍不识别,可将InfinityFree的根证书导入项目:

  • 从InfinityFree下载根证书(.pem格式),重命名为certificate.pem后放到项目res/raw目录
  • 创建自定义HurlStack来信任该证书:
import android.content.Context;
import android.util.Log;
import com.android.volley.toolbox.HurlStack;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

public class CustomHurlStack extends HurlStack {
    private SSLSocketFactory sslSocketFactory;

    public CustomHurlStack(Context context) {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = context.getResources().openRawResource(R.raw.certificate);
            X509Certificate ca;
            try {
                ca = (X509Certificate) cf.generateCertificate(caInput);
            } finally {
                caInput.close();
            }

            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);
            sslSocketFactory = sslContext.getSocketFactory();
        } catch (Exception e) {
            Log.e("CustomHurlStack", e.getMessage());
        }
    }

    @Override
    protected javax.net.ssl.HttpsURLConnection createHttpsConnection(String url) throws java.io.IOException {
        javax.net.ssl.HttpsURLConnection connection = (javax.net.ssl.HttpsURLConnection) super.createHttpsConnection(url);
        connection.setSSLSocketFactory(sslSocketFactory);
        return connection;
    }
}
  • 创建Volley请求队列时使用该自定义栈:
RequestQueue queue = Volley.newRequestQueue(this, new CustomHurlStack(this));

3. 临时绕过SSL验证(仅测试用,禁止生产环境使用)

如果只是测试阶段,可临时禁用SSL验证,但会带来安全风险:

import com.android.volley.toolbox.HurlStack;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class UnsafeHurlStack extends HurlStack {
    @Override
    protected javax.net.ssl.HttpsURLConnection createHttpsConnection(String url) throws java.io.IOException {
        javax.net.ssl.HttpsURLConnection connection = (javax.net.ssl.HttpsURLConnection) super.createHttpsConnection(url);
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) {}

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) {}

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            }}, null);
            connection.setSSLSocketFactory(sslContext.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }
}
  • 使用方式:
RequestQueue queue = Volley.newRequestQueue(this, new UnsafeHurlStack());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:08:09