我试图连接到一个运行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加密安全,而没有中间人攻击的危险!

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

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

我在这里分享我在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)

    }

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

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

回复一个很旧的帖子。但也许它会帮助一些新手,如果以上都行不通的话。

解释:我知道没人想听废话解释;而是解决方案。但是在一行代码中,您试图从本地计算机访问服务到不信任您的计算机的远程计算机。您的请求需要获得远程服务器的信任。

解决方案:下面的解决方案假设您满足以下条件

试图从本地机器访问远程api。 你正在为Android应用开发 您的远程服务器在代理过滤下(您在浏览器设置中使用代理来访问远程api服务,通常是登台或开发服务器) 你是在真实的设备上测试

步骤:

你需要一个.keystore扩展文件来注册你的应用。如果你不知道如何创建.keystore文件;然后按照以下小节创建.keystore文件,否则跳转到下一小节签署Apk文件

创建.keystore文件

打开Android Studio。单击顶部菜单Build > Generate Signed APK。在下一个窗口中单击Create new…按钮。在新窗口中,请在所有字段中输入数据。记住我建议的两个密码字段应该有相同的密码;不要使用不同的密码;并且记住最上面字段的保存路径键存储路径:。输入所有字段后单击OK按钮。

签署Apk文件

现在需要使用刚才创建的.keystore文件构建一个签名应用程序。遵循以下步骤

Build > Clean Project, wait till it finish cleaning Build > Generate Signed APK Click Choose existing... button Select the .keystore file we just created in the Create .keystore file section Enter the same password you created while creating in Create .keystore file section. Use same password for Key store password and Key password fields. Also enter the alias Click Next button In the next screen; which might be different based on your settings in build.gradle files, you need to select Build Types and Flavors. For the Build Types choose release from the dropdown For Flavors however it will depends on your settings in build.gradle file. Choose staging from this field. I used the following settings in the build.gradle, you can use the same as mine, but make sure you change the applicationId to your package name productFlavors { staging { applicationId "com.yourapplication.package" manifestPlaceholders = [icon: "@drawable/ic_launcher"] buildConfigField "boolean", "CATALYST_DEBUG", "true" buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "true" } production { buildConfigField "boolean", "CATALYST_DEBUG", "false" buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "false" } } Click the bottom two Signature Versions checkboxes and click Finish button.

几乎有:

所有艰苦的工作都完成了,现在是真理的运动。为了访问通过代理备份的登台服务器,您需要在您的实际测试Android设备中进行一些设置。

Android设备的代理设置:

点击Android手机内的设置,然后点击wi-fi 长按已连接的wifi,选择“修改网络” 如果看不到代理主机名字段,则单击高级选项 在代理主机名中输入要连接的主机IP或名称。典型的登台服务器将命名为stg.api.mygoodcompany.com 端口输入四位数端口号,例如9502 点击保存按钮

最后一站:

记住,我们在签名apk文件部分生成了签名apk文件。现在是时候安装APK文件了。

打开终端,更改为已签名的apk文件夹 将你的Android设备连接到你的机器 从Android设备中删除之前安装的apk文件 执行adb安装apk文件的名称 如果由于某种原因,上述命令返回adb命令没有找到。填写完整路径为:C:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe安装apk文件的名称

我希望问题能得到解决。如果没有,请给我留言。

萨拉姆!

我知道你不需要信任所有的证书,但在我的案例中,我在一些调试环境中遇到了问题,我们有自签名证书,我需要一个脏的解决方案。

我所要做的就是改变sslContext的初始化

mySSLContext.init(null, trustAllCerts, null); 

其中trustAllCerts是这样创建的:

private final TrustManager[] trustAllCerts= new TrustManager[] { new X509TrustManager() {
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return new java.security.cert.X509Certificate[]{};
    }

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

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

希望这能派上用场。