SSLHandshakeException:PKIX 路径构建失败 SunCertPathBuilderException:无法找到请求目标的有效证书路径
Posted
技术标签:
【中文标题】SSLHandshakeException:PKIX 路径构建失败 SunCertPathBuilderException:无法找到请求目标的有效证书路径【英文标题】:SSLHandshakeException: PKIX path building failed SunCertPathBuilderException: unable to find valid certification path to requested target 【发布时间】:2020-11-25 05:58:05 【问题描述】:我已将 PEM 文件 cert.crt.pem 和 cert.key.pem 复制到文件路径中,并在使用详细信息 url、消息类型、pem 文件和密码为 REST 服务执行以下代码时,出现错误“SSLHandshakeException”。
例外:
连接示例:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径
代码:
class RestWebServicePEM
public static void main(String[] args)
String url = "<authenticate_url>";
String msgType = "application/json";
String method = "POST";
String pass = "<password>";
File certKeyFile = new File("cert.crt.pem");
File privateKeyFile = new File("cert.key.pem");
HttpsURLConnection con = getSslConnection(url, msgType, method, privateKeyFile, certKeyFile, pass);
int responseCode = con.getResponseCode();
private HttpsURLConnection getSslConnection(String inUrl, String inMsgType, String inMethod,
File privateKeyPem, File certificatePem, String password)
HttpsURLConnection con = null;
SocketFactory sslSocketFactory = createSSLSocketFactory(privateKeyPem, certificatePem, password);
HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
try
URL url = new URL(inUrl);
con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory(sslSocketFactory);
if (inMethod == "POST")
con.setRequestMethod(inMethod);
con.setDoOutput(true);
con.setInstanceFollowRedirects(true);
con.setConnectTimeout(30000);
con.setReadTimeout(30000);
con.setRequestProperty("Content-Type", inMsgType);
con.connect();
catch (Exception e)
if (con)
con.disconnect();
con = null;
return con;
private SSLSocketFactory createSSLSocketFactory(File privateKeyPem, File certificatePem, String password) throws Exception
SSLContext context = SSLContext.getInstance("TLS");
KeyStore keystore = createKeyStore(privateKeyPem, certificatePem, password);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keystore, password.toCharArray());
KeyManager[] km = kmf.getKeyManagers();
context.init(km, null, null);
return context.getSocketFactory();
private KeyStore createKeyStore(File privateKeyPem, File certificatePem, final String password)
throws Exception, KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException
X509Certificate[] cert = createCertificates(certificatePem);
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(null);
PrivateKey key = createPrivateKey(privateKeyPem);
keystore.setKeyEntry(privateKeyPem.getName(), key, password.toCharArray(), cert);
return keystore;
private PrivateKey createPrivateKey(File privateKeyPem) throws Exception
BufferedReader r = new BufferedReader(new FileReader(privateKeyPem));
String s = r.readLine();
while (s != null)
if (s.contains("BEGIN PRIVATE KEY"))
break;
s = r.readLine();
StringBuilder b = new StringBuilder();
s = "";
while (s != null)
if (s.contains("END PRIVATE KEY"))
break;
b.append(s);
s = r.readLine();
r.close();
String hexString = b.toString();
byte[] bytes = DatatypeConverter.parseBase64Binary(hexString);
return generatePrivateKeyFromDER(bytes);
private X509Certificate[] createCertificates(File certificatePem) throws Exception
List<X509Certificate> result = new ArrayList<X509Certificate>();
BufferedReader r = new BufferedReader(new FileReader(certificatePem));
String s = r.readLine();
while (s != null)
if (s.contains("BEGIN CERTIFICATE"))
break;
s = r.readLine();
StringBuilder b = new StringBuilder();
while (s != null)
if (s.contains("END CERTIFICATE"))
String hexString = b.toString();
final byte[] bytes = DatatypeConverter.parseBase64Binary(hexString);
X509Certificate cert = generateCertificateFromDER(bytes);
result.add(cert);
addMessage("Certificate:"+cert);
b = new StringBuilder();
else
if (!s.startsWith("----"))
b.append(s);
s = r.readLine();
r.close();
return result.toArray(new X509Certificate[result.size()]);
private RSAPrivateKey generatePrivateKeyFromDER(byte[] keyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return (RSAPrivateKey) factory.generatePrivate(spec);
private X509Certificate generateCertificateFromDER(byte[] certBytes) throws CertificateException
CertificateFactory factory = CertificateFactory.getInstance("X.509");
return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certBytes));
【问题讨论】:
【参考方案1】:您可以通过将证书添加到 Java 密钥库来解决此问题。
下载证书。
转到路径
把证书放在这里。
运行key tool命令(管理员模式)如果要求输入密码(changeit)
keytool -keystore cacerts -importcert -alias "你的别名" -file certificare name.cer
5.现在您可以删除 SSL 验证码了。
【讨论】:
以上是关于SSLHandshakeException:PKIX 路径构建失败 SunCertPathBuilderException:无法找到请求目标的有效证书路径的主要内容,如果未能解决你的问题,请参考以下文章
Scala:如何忽略“SSLHandshakeException”
SSLHandshakeException 无法验证用户身份
SSLHandshakeException:不存在主题替代名称