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

 

 

 

方案1

try {
  CertificateFactory cf = CertificateFactory.getInstance("X.509");
  // uwca.crt 打包在 asset 中,该证书可以从https://itconnect.uw.edu/security/securing-computer/install/safari-os-x/下载
  InputStream caInput = new BufferedInputStream(getAssets().open("uwca.crt"));
  Certificate ca;
  try {
      ca = cf.generateCertificate(caInput);
      Log.i("Longer", "ca=" + ((X509Certificate) ca).getSubjectDN());
      Log.i("Longer", "key=" + ((X509Certificate) ca).getPublicKey();
  } finally {
      caInput.close();
  }

  // Create a KeyStore containing our trusted CAs
  String keyStoreType = KeyStore.getDefaultType();
  KeyStore keyStore = KeyStore.getInstance(keyStoreType);
  keyStore.load(null, null);
  keyStore.setCertificateEntry("ca", ca);

  // Create a TrustManager that trusts the CAs in our KeyStore
  String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
  TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
  tmf.init(keyStore);

  // Create an SSLContext that uses our TrustManager
  SSLContext context = SSLContext.getInstance("TLSv1","AndroidOpenSSL");
  context.init(null, tmf.getTrustManagers(), null);

  URL url = new URL("https://certs.cac.washington.edu/CAtest/");
  HttpsURLConnection urlConnection =
          (HttpsURLConnection)url.openConnection();
  urlConnection.setSSLSocketFactory(context.getSocketFactory());
  InputStream in = urlConnection.getInputStream();
  copyInputStreamToOutputStream(in, System.out);
} catch (CertificateException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
} catch (KeyStoreException e) {
  e.printStackTrace();
} catch (KeyManagementException e) {
  e.printStackTrace();
} catch (NoSuchProviderException e) {
  e.printStackTrace();
}

方案2

同方案1,打包一份到证书到 app 内部,但不通过KeyStore去引导生成的TrustManager,而是干脆直接自定义一个TrustManager,自己实现校验逻辑;校验逻辑主要包括:

•服务器证书是否过期
•证书签名是否合法

try {
  CertificateFactory cf = CertificateFactory.getInstance("X.509");
  // uwca.crt 打包在 asset 中,该证书可以从https://itconnect.uw.edu/security/securing-computer/install/safari-os-x/下载
  InputStream caInput = new BufferedInputStream(getAssets().open("uwca.crt"));
  final Certificate ca;
  try {
      ca = cf.generateCertificate(caInput);
      Log.i("Longer", "ca=" + ((X509Certificate) ca).getSubjectDN());
      Log.i("Longer", "key=" + ((X509Certificate) ca).getPublicKey());
  } finally {
      caInput.close();
  }
  // Create an SSLContext that uses our TrustManager
  SSLContext context = SSLContext.getInstance("TLSv1","AndroidOpenSSL");
  context.init(null, new TrustManager[]{
          new X509TrustManager() {
              @Override
              public void checkClientTrusted(X509Certificate[] chain,
                      String authType)
                      throws CertificateException {

              }

              @Override
              public void checkServerTrusted(X509Certificate[] chain,
                      String authType)
                      throws CertificateException {
                  for (X509Certificate cert : chain) {

                      // Make sure that it hasn't expired.
                      cert.checkValidity();

                      // Verify the certificate's public key chain.
                      try {
                          cert.verify(((X509Certificate) ca).getPublicKey());
                      } catch (NoSuchAlgorithmException e) {
                          e.printStackTrace();
                      } catch (InvalidKeyException e) {
                          e.printStackTrace();
                      } catch (NoSuchProviderException e) {
                          e.printStackTrace();
                      } catch (SignatureException e) {
                          e.printStackTrace();
                      }
                  }
              }

              @Override
              public X509Certificate[] getAcceptedIssuers() {
                  return new X509Certificate[0];
              }
          }
  }, null);

  URL url = new URL("https://certs.cac.washington.edu/CAtest/");
  HttpsURLConnection urlConnection =
          (HttpsURLConnection)url.openConnection();
  urlConnection.setSSLSocketFactory(context.getSocketFactory());
  InputStream in = urlConnection.getInputStream();
  copyInputStreamToOutputStream(in, System.out);
} catch (CertificateException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
} catch (KeyManagementException e) {
  e.printStackTrace();
} catch (NoSuchProviderException e) {
  e.printStackTrace();
}

方案3(推荐) 


    //证书信任
    public final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
//证书信任
//关键代码
if (url.getProtocol().toUpperCase().equals("HTTPS")) {
        trustAllHosts();
        HttpsURLConnection https = (HttpsURLConnection) url
                .openConnection();
        https.setHostnameVerifier(DO_NOT_VERIFY);
        conn = https;
    } else {
        conn = (HttpURLConnection) url.openConnection();
    }
//关键代码

    public static void trustAllHosts() {
        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 {
            }
        }};
        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection
                    .setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: pkix路径验证失败: java.security.cert.certpathvalidatorexception: 有效性检查失败。 这个错误通常是由于证书链中的某个证书过期或无效导致的。在进行SSL/TLS握手时,服务器会向客户端发送证书链,客户端会验证证书链的有效性。如果证书链中的任何一个证书无效,就会出现这个错误。解决方法是更新证书链中的证书或者使用其他可信的证书链。 ### 回答2: PKIX路径验证失败是指使用PKIX(公钥基础设施)验证证书链时发生了错误。在此过程中,Java代码检查公共信任点库中的证书,并验证它们是否信任所提供证书链中每个证书的发行者。如果整个证书链都被信任,则验证成功。但是,如果任何一个证书无效或未能通过验证,则将出现pkix路径验证失败错误。 在检查整个证书链时,Java API会验证每个证书的有效期、签名和可信性。证书的有效期是指证书在什么时间段内是有效的。签名是证书由发布者签名的证明。可信性是证书签名者的可信度和证书是否被吊销。 如果任何上述条件未能通过Java API的验证,则会抛出pkix路径验证失败错误。 解决此问题的方法包括: 1. 检查证书是否过期或未被撤销。可以手动检查证书是否在其有效期内,并使用在线撤销列表(CRL)工具来确定证书是否已被吊销。 2. 检查证书链是否完整。证书链应包含所有必要的证书以验证证书链中的每个证书。 3. 更新Java安全策略。检查Java安全性选项是否正确配置。 4. 检查TLS / SSL协议和密钥库的设置。在TLS / SSL协议中,密钥库(包含证书)可能需要正确配置。 总之,pkix路径验证失败错误通常意味着代码无法验证证书链中某个证书的有效性。可以通过检查证书是否过期、更新Java安全策略以及检查TLS / SSL协议和密钥库的设置来解决这个问题。 ### 回答3: PKIX路径验证失败是指在使用PKI(公钥基础设施)模型进行证书验证时发生了验证失败的情况。在Java中,当证书链验证过程中发现证书过期、无效、不匹配、签名不正确等问题时,就会抛出java.security.cert.CertPathValidatorException异常。其中,validity check failed的具体含义是验证证书的有效期限时发现证书已过期或未到有效期限。 在实际应用中,PKIX路径验证失败的原因可能有很多,如证书链不完整、证书颁发机构无效、证书格式不正确、证书不可信或被篡改等。这些问题通常需要管理员或开发人员通过查看日志、检查证书链和配置、更新证书等手段逐一排查。同时,建议使用最新的证书库和算法,并实现安全的证书管理机制,以尽可能提高证书验证的成功率和安全性。 在解决PKIX路径验证失败的问题时,建议保持耐心和恒心,理性分析问题并及时采取有效措施,同时加强对证书验证相关知识的学习和了解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值