我试图连接到一个运行godaddy 256bit SSL证书的IIS6盒子,我得到了错误:

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

我一直在想是什么原因导致的,但目前还没有头绪。

以下是我的联系方式:

HttpsURLConnection conn;              
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream());

当前回答

在我的例子中,这发生在更新到Android 8.0之后。Android设置为信任的自签名证书使用的是签名算法SHA1withRSA。切换到新的证书,使用签名算法sha256withthrsa解决了这个问题。

其他回答

如果你使用了改装,你需要定制你的OkHttpClient。

retrofit =新的retrofit . builder () .baseUrl (ApplicationData.FINAL_URL) .build .client (getUnsafeOkHttpClient () ()) .addConverterFactory (GsonConverterFactory.create ()) .build ();

完整代码如下。

public class RestAdapter {

    private static Retrofit retrofit = null;
    private static ApiInterface apiInterface;

    public static OkHttpClient.Builder getUnsafeOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                    }
                }
            };
    
                // Install the all-trusting trust manager
                final SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
    
                // Create an ssl socket factory with our all-trusting manager
                final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
    
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
                builder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
                return builder;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        
        public static ApiInterface getApiClient() {
            if (apiInterface == null) {
    
                try {
                    retrofit = new Retrofit.Builder()
                            .baseUrl(ApplicationData.FINAL_URL)
                            .client(getUnsafeOkHttpClient().build())
                            .addConverterFactory(GsonConverterFactory.create())
                            .build();
    
                } catch (Exception e) {
    
                    e.printStackTrace();
                }
    
    
                apiInterface = retrofit.create(ApiInterface.class);
            }
            return apiInterface;
        }
        
    }

@Chrispix的解决方案是危险的!相信所有的证书允许任何人做一个人在中间攻击!只要向客户端发送任何证书,它就会接受它!

将您的证书添加到自定义信任管理器,如本文所述:通过HTTPS使用HttpClient信任所有证书

虽然使用自定义证书建立安全连接有点复杂,但它将为您带来所需的ssl加密安全,而没有中间人攻击的危险!

与公认的答案相反,您不需要自定义信任管理器,您需要修复您的服务器配置!

我在连接Apache服务器时遇到了同样的问题,该服务器错误地安装了dynadot/alphassl证书。我正在使用HttpsUrlConnection (Java/Android)连接,这是抛出-

javax.net.ssl.SSLHandshakeException: 
  java.security.cert.CertPathValidatorException: 
    Trust anchor for certification path not found.

实际的问题是服务器配置错误——用http://www.digicert.com/help/或类似工具测试,它甚至会告诉你解决方案:

证书不是由受信任的权威机构签署的(根据Mozilla的根存储进行检查)。如果您从受信任的权威机构购买了证书,则可能只需要安装一个或多个中间证书。请与您的证书提供商联系,以便在您的服务器平台上执行此操作。”

您也可以在openssl中查看证书:

Openssl s_client -debug -connect www.thedomaintocheck.com:443

你可能会看到:

验证返回码:21(无法验证第一个证书)

在前面的输出中:

depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`

证书链将只包含1个元素(您的证书):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
  i:/O=AlphaSSL/CN=AlphaSSL CA - G2

... 但是应该引用链中的签名授权,回到Android信任的授权(Verisign, GlobalSign等):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
   i:/O=AlphaSSL/CN=AlphaSSL CA - G2
 1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA

配置服务器的说明(和中间证书)通常由颁发证书的机构提供,例如:http://www.alphassl.com/support/install-root-certificate.html

在安装了我的证书颁发者提供的中间证书之后,我现在在使用HttpsUrlConnection连接时没有错误。

In my case, the root & intermediate certificates was successfully installed but I still got "Trust anchor for certification path not found." exception!. After digging the android document, found out that by default, secure connections (using protocols like TLS and HTTPS) from all apps trust the pre-installed system CAs, and apps targeting Android 6.0 (API level 23) and lower also trust the user-added CA store by default. If your app running on a OS with api level higher than 23 you should explicitly allow the app to trust user-added CA by adding its address to network_security_config like bellow:

<domain-config>
        <domain includeSubdomains="true">PUT_YOUR_SERVER_ADDERESS</domain>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
</domain-config>

在我的情况下,网站中的证书是正确的(发行人= GlobalSign RSA OV SSL CA 2018),但我下载的证书文件是错误的,因为防病毒正在“拦截”证书,并提供一个新的不同的证书从浏览器下载(发行人= ESET SSL过滤器CA) !!

检查证书文件的颁发者是否正确。