我试图连接到一个运行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客户端连接到Kurento服务器时遇到了同样的问题。 Kurento服务器使用jks证书,所以我必须将pem转换为它。 作为转换的输入,我使用cert.pem文件,它会导致这样的错误。 但如果使用全链。pem,而不是cert.pem - all是OK的。

其他回答

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

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

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

您可以在运行时信任特定的证书。 只需从服务器下载,放入资产,然后使用ssl-utils-android像这样加载:

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

在上面的例子中,我使用了OkHttpClient,但是SSLContext可以用于Java中的任何客户端。

如果你有任何问题,请提出来。我是这个小图书馆的作者。

如果你使用了改装,你需要定制你的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;
        }
        
    }

根据最新的Android文档(2017年3月)更新:

当你得到这种类型的错误:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
        at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
        at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
        at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
        at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
        at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
        at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

问题可能是以下情况之一:

颁发服务器证书的CA未知 服务器证书不是由CA签署的,而是自签署的 服务器配置缺少一个中间CA

解决方案是教会HttpsURLConnection信任一组特定的ca。怎么做?请查看https://developer.android.com/training/articles/security-ssl.html#CommonProblems

其他使用com.loopj的AsyncHTTPClient的人。android:android-async-http库,请检查设置AsyncHttpClient使用HTTPS。

我也遇到过类似的问题,我已经完全排除了相信所有消息来源的策略。

我在这里分享我在Kotlin中实现的应用程序中的解决方案

我首先建议使用以下网站获取有关证书及其有效性的信息

如果它不在Android默认信任存储中显示为“已接受的发行者”,我们必须获得该证书并将其合并到应用程序中以创建自定义信任存储

在我的案例中,理想的解决方案是创建一个高级信任管理器,它结合了自定义和Android默认信任存储

在这里,他公开了用于配置他与Retrofit一起使用的OkHttpClient的高级代码。

override fun onBuildHttpClient(httpClientBuild: OkHttpClient.Builder) {

        val trustManagerWrapper = createX509TrustManagerWrapper(
            arrayOf(
                getCustomX509TrustManager(),
                getDefaultX509TrustManager()
            )
        )

        printX509TrustManagerAcceptedIssuers(trustManagerWrapper)

        val sslSocketFactory = createSocketFactory(trustManagerWrapper)
        httpClientBuild.sslSocketFactory(sslSocketFactory, trustManagerWrapper)

    }

通过这种方式,我可以使用自签名证书与服务器通信,也可以使用受信任的证书实体颁发的证书与其他服务器通信

就是这个,我希望它能帮助到一些人。