我试图连接到一个运行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());

当前回答

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>

其他回答

我知道这是一篇非常古老的文章,但我在尝试解决信任锚问题时遇到了这篇文章。我已经发布了我是如何修复它的。如果您已经预安装了根CA,则需要向清单中添加配置。

https://stackoverflow.com/a/60102517/114265

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

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

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

试图从本地机器访问远程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文件的名称

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

萨拉姆!

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

我在连接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连接时没有错误。

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

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

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

我使用这些方法,其中一个是上述解决方案对我有效: 第一:

   public  okhttp3.OkHttpClient 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();

        okhttp3.OkHttpClient.Builder builder = new 
      okhttp3.OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory, 
      (X509TrustManager)trustAllCerts[0]);
        builder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession 
       session) {
                return true;
            }
        });

        okhttp3.OkHttpClient okHttpClient = builder.build();
        return okHttpClient;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

第二:

    @SuppressLint("TrulyRandom")
    public static void handleSSLHandshake() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[]{new 
       X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }

            @Override
            public void checkClientTrusted(X509Certificate[] 
        certs, String authType) {
            }

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

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        



  HttpsURLConnection
 .setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new 
    HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
    } catch (Exception ignored) {
    }
}

和: 把这些库放到你的类路径中:

 implementation 'com.squareup.okhttp:okhttp:2.3.0'
implementation 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
    androidTestImplementation 'androidx.test.espresso:espresso- 
    core:3.3.0'

一定要在课堂上给他们打电话