Java使用JKS证书通过GET调用REST API出现证书错误如何解决
错误原因
你遇到的PKIX path validation failed: validity check failed报错有两个核心触发原因:
- 你的代码未加载持有的JKS证书配置到HTTPS请求的SSL上下文,Java默认会使用JRE内置的
cacerts信任库做证书校验,你调用的接口证书不在默认信任库中,验证直接失败。 - 也有可能是JKS中的证书已过期,或者你本地操作系统时间不在证书的有效时间范围内,可以先排查这两个基础项。
修复方案
步骤1:确认基础信息
提前确认你的JKS证书文件路径、JKS访问密码,确认JKS中已正确导入目标接口的服务端证书链。
步骤2:修改代码加载JKS证书
修改后的完整代码如下:
package com.barclays.ods.utils; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import java.io.*; import java.net.URL; import java.security.KeyStore; public class ODSRouteCheckUtility { // 替换为你实际的JKS文件路径 private static final String JKS_PATH = "/your/path/to/cert.jks"; // 替换为你实际的JKS访问密码 private static final String JKS_PASSWORD = "your_jks_password"; public static void main(String[] args) throws Exception { String odsGlossUrl = "https://testurl/df-web/Query" ; //args[0]; // 预先加载JKS初始化SSL上下文 initSSLContext(); MyGETRequest(odsGlossUrl); } /** * 加载JKS证书初始化SSL上下文 */ private static void initSSLContext() throws Exception { KeyStore trustStore = KeyStore.getInstance("JKS"); try (FileInputStream fis = new FileInputStream(JKS_PATH)) { trustStore.load(fis, JKS_PASSWORD.toCharArray()); } TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(trustStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); } public static void MyGETRequest(String odsGlossUrl) throws IOException { URL urlForGetRequest = new URL(odsGlossUrl); String readLine = null; // 这里要转成HttpsURLConnection,不要用HttpURLConnection HttpsURLConnection connection = (HttpsURLConnection) urlForGetRequest.openConnection(); connection.setRequestMethod("GET"); int responseCode = connection.getResponseCode(); if (responseCode == HttpsURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream())); StringBuilder response = new StringBuilder(); while ((readLine = in.readLine()) != null) { response.append(readLine); } in.close(); System.out.println("JSON String Result " + response.toString()); } else { System.out.println("GET NOT WORKED, response code: " + responseCode); } } private static void readFromStream(InputStream response) throws Exception { try (BufferedReader br = new BufferedReader(new InputStreamReader(response))) { String strCurrentLine; while ((strCurrentLine = br.readLine()) != null) { System.out.println(strCurrentLine); } } catch (Exception e) { e.printStackTrace(); throw e; } } }
临时测试方案(生产环境禁止使用)
如果只是本地测试用,不需要校验证书,可以用跳过证书验证的方案,把initSSLContext方法替换为以下实现即可:
private static void initSSLContext() throws Exception { TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true); }
内容的提问来源于stack exchange,提问作者Anu Shivangi
相关产品推荐
相关产品推荐

