SSL - SSLHandshakeException: unable to find valid certification path to requested target
一、異常日誌
javax.net.ssl.SSLHandshakeException
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 18 more
二、解決方案
因缺少安全證照出現的異常,可通過下面的方式將服務端的安全認證證照匯入到客戶端
1、編譯如下工具類
package cert;
/*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class InstallCert {
public static void main(String[] args) throws Exception {
String host;
int port;
char[] passphrase;
if ((args.length == 1) || (args.length == 2)) {
String[] c = args[0].split(":");
host = c[0];
port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
String p = (args.length == 1) ? "changeit" : args[1];
passphrase = p.toCharArray();
} else {
System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
return;
}
File file = new File("jssecacerts");
if (file.isFile() == false) {
char SEP = File.separatorChar;
File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security");
file = new File(dir, "jssecacerts");
if (file.isFile() == false) {
file = new File(dir, "cacerts");
}
}
System.out.println("Loading KeyStore " + file + "...");
InputStream in = new FileInputStream(file);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(in, passphrase);
in.close();
SSLContext context = SSLContext.getInstance("TLS");
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
context.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory factory = context.getSocketFactory();
System.out.println("Opening connection to " + host + ":" + port + "...");
SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
socket.setSoTimeout(10000);
try {
System.out.println("Starting SSL handshake...");
socket.startHandshake();
socket.close();
System.out.println();
System.out.println("No errors, certificate is already trusted");
} catch (SSLException e) {
System.out.println();
e.printStackTrace(System.out);
}
X509Certificate[] chain = tm.chain;
if (chain == null) {
System.out.println("Could not obtain server certificate chain");
return;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println();
System.out.println("Server sent " + chain.length + " certificate(s):");
System.out.println();
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
MessageDigest md5 = MessageDigest.getInstance("MD5");
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = chain[i];
System.out.println(" " + (i + 1) + " Subject " + cert.getSubjectDN());
System.out.println(" Issuer " + cert.getIssuerDN());
sha1.update(cert.getEncoded());
System.out.println(" sha1 " + toHexString(sha1.digest()));
md5.update(cert.getEncoded());
System.out.println(" md5 " + toHexString(md5.digest()));
System.out.println();
}
System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
String line = reader.readLine().trim();
int k;
try {
k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
} catch (NumberFormatException e) {
System.out.println("KeyStore not changed");
return;
}
X509Certificate cert = chain[k];
String alias = host + "-" + (k + 1);
ks.setCertificateEntry(alias, cert);
OutputStream out = new FileOutputStream("jssecacerts");
ks.store(out, passphrase);
out.close();
System.out.println();
System.out.println(cert);
System.out.println();
System.out.println("Added certificate to keystore 'jssecacerts' using alias '" + alias + "'");
}
private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
private static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 3);
for (int b : bytes) {
b &= 0xff;
sb.append(HEXDIGITS[b >> 4]);
sb.append(HEXDIGITS[b & 15]);
sb.append(' ');
}
return sb.toString();
}
private static class SavingTrustManager implements X509TrustManager {
private final X509TrustManager tm;
private X509Certificate[] chain;
SavingTrustManager(X509TrustManager tm) {
this.tm = tm;
}
public X509Certificate[] getAcceptedIssuers() {
throw new UnsupportedOperationException();
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
throw new UnsupportedOperationException();
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
this.chain = chain;
tm.checkServerTrusted(chain, authType);
}
}
}
2、執行 java InstallCert hostname,比如:java InstallCert www.twitter.com 或 java InstallCert 101.231.204.80:5000。然後可以看到如下日誌
[root@local usr]$ java InstallCert 101.231.204.80:5000
Loading KeyStore /usr/java/jdk1.7.0_55/jre/lib/security/cacerts...
Opening connection to 101.231.204.80:5000...
Starting SSL handshake...
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at cert.InstallCert.main(InstallCert.java:98)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:107)
at cert.InstallCert$SavingTrustManager.checkServerTrusted(InstallCert.java:189)
at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:813)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)
... 8 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
... 16 more
Server sent 1 certificate(s):
1 Subject CN=101.231.204.80, OU=Local RA, O=cfca, L=beijing, ST=beijing, C=CN
Issuer CN=101.231.204.80, OU=Local RA, O=cfca, L=beijing, ST=beijing, C=CN
sha1 02 eb 09 66 15 ec a3 c4 d8 8e f6 4f e5 a7 a9 18 3e 02 23 01
md5 64 9f 16 3b e7 95 a6 a2 14 a6 79 de 9e 82 78 17
Enter certificate to add to trusted keystore or 'q' to quit: [1]
3、根據提示輸入 1 ,會看到如下日誌
1
[
[
Version: V3
Subject: CN=101.231.204.80, OU=Local RA, O=cfca, L=beijing, ST=beijing, C=CN
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
modulus: 27046836126329656084021915372821670843451536300460607349030517292404890084799178086846617620738935902888712284603725485401688160327085116409553281451072821171829251692829997697184241960076922057414797279941386914233404377962849519705096898302532673605044905252381354661149660263864618166316903627311506815380962630271597252372061967018070023082540931349957578186959391961135716686695602385932530405406600044526797585516408002645028319196281430260529530215108676165655053787659565528243256834915620979491199423351369510848526762486371845423831506230623973510957108819507437170927278403535409991979426324853850572293293
public exponent: 65537
Validity: [From: Mon Apr 10 21:49:35 CST 2017,
To: Tue Apr 10 21:49:35 CST 2018]
Issuer: CN=101.231.204.80, OU=Local RA, O=cfca, L=beijing, ST=beijing, C=CN
SerialNumber: [ 0dade1ef]
]
Algorithm: [SHA256withRSA]
Signature:
0000: B0 69 4A 5C A1 84 78 47 27 41 24 36 F9 F1 E1 3D .iJ\..xG'A$6...=
0010: 1B E3 5E C6 B4 4D 4E E0 CB A4 DF 9A 3F 39 74 33 ..^..MN.....?9t3
0020: BC E7 98 D7 B3 24 CD 7C 91 92 FD 8C 9E 7B 89 B8 .....$..........
0030: 54 A3 6E F4 DA D1 99 1A 6B 35 7B C9 52 C8 6A E8 T.n.....k5..R.j.
0040: C8 16 F8 4B 92 EA 17 8B CF 32 EA B7 5C 3D 95 DC ...K.....2..\=..
0050: 73 EE BA 1D E8 B1 6A 46 96 48 F8 97 79 58 BA 48 s.....jF.H..yX.H
0060: 7B F2 56 A2 80 A9 4B B2 B7 7F 7B 09 51 66 A8 C8 ..V...K.....Qf..
0070: F4 B2 1F 96 47 62 81 92 2C D3 13 20 4B B9 B5 8E ....Gb..,.. K...
0080: 12 7E 46 BA D7 34 AF 6D 7F 1B 3D 44 5D 26 15 AC ..F..4.m..=D]&..
0090: 9E D2 2A 77 EC 34 6D 22 A1 85 38 5B 95 2C C7 70 ..*w.4m"..8[.,.p
00A0: 4A EC 51 F0 4A 2B 21 9D 56 46 6E 18 9F 50 1D E5 J.Q.J+!.VFn..P..
00B0: F7 8C BD 50 DB FE 57 9C CD 14 EC 1F B2 37 E7 47 ...P..W......7.G
00C0: AA 05 1E 7F 62 53 22 26 FD 78 E4 C2 54 43 D0 BE ....bS"&.x..TC..
00D0: 23 7C 75 16 85 EE 40 F2 51 70 AA C6 B5 E5 0F 52 #.u...@.Qp.....R
00E0: 2B DC E8 CE 54 0C 94 09 80 85 B9 76 8C 46 99 9C +...T......v.F..
00F0: C6 66 7F B9 EC 36 C5 97 39 A9 31 D0 05 08 8C 71 .f...6..9.1....q
]
Added certificate to keystore 'jssecacerts' using alias '101.231.204.80-1'
4、此時在當面目錄下已經生成了一個名為jssecacerts的證照,將這個的證照拷貝到 /%JAVA_HONME%/jre/lib/security/ 目錄中,或者使用System.setProperty("javax.net.ssl.trustStore", "jssecacerts證照路徑") 載入證照即可
相關文章
- SSL - SSLHandshakeException: Unrecognized SSL message, plaintext connection?ExceptionZedAI
- SSL - SSLHandshakeException: No subject alternative names presentException
- Unable to find a specification for ''
- CertPathValidatorException: Trust anchor for certification path not found解決方法ExceptionRust
- Please provide a valid cache pathIDE
- SSL - SSLHandshakeException: No subject alternative names matching IP address foundException
- eslint-plugin-import Unable to resolve path to moduleEsLintPluginImport
- 解決 javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateExceptionJavaException
- [20180806]ORA-16606 unable to find property.txt
- MySQL5.7 Unable to find a match: MySQL-community-serverMySqlUnityServer
- OPatch cannot find a valid oraInst.loc file to locate Central InventoryAI
- Cannot find a valid baseurl for repo: base/7/x86_64
- git SSL certificate problem: unable to get local issuer certificateGit
- ERROR | [iOS] unknown: Encountered an unknown error (Could not find a `ios` simulator (valid values:ErroriOS
- Android Bugs—— Error:In declare-styleable FontFamilyFont, unable to find attribute android:fontAndroidError
- 終端報錯"xcrun: error: unable to find utility “xcodebuild”, not a developer tool orErrorXCodeUIDeveloper
- find /path/to/search -type d -perm -o=x ! -perm -o=rw
- Failed ALPN negotiation: Unable to find compatible protocol&&subscriptionExpressions have not been set yetAIGoProtocolExpress
- [GuzzleHttp\Exception\RequestException] cURL error 60: SSL certificate problem: unable to get localHTTPExceptionError
- GIT clone報錯: SSL certificate problem: unable to get local issuer certificateGit
- All mirror URLs are not using ftp, http[s] or file. Cannot find a valid baseurl for repo: baseFTPHTTP
- 已解決:Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986 問題
- 記一次 報錯:Android ClassNotFoundException: Didn't find class on pathAndroidException
- nancy Unable to find view engine that could render the view 無法找到檢視模板引擎NaNView
- CentOS7中使用yum安裝時報cannot find a valid baseurl for repo錯誤CentOS
- Linux: Centos7 Cannot find a valid baseurl for repo: base/7/x86_64 解決方案LinuxCentOS
- file_get_content s()獲取https出現這個錯誤Unable to find the wrapperHTTPAPP
- Openfiler配置ISCSI Target及FC Target
- Requested setting INSTALLED_APPSAPP
- WebStorm Exception: ...requested without authorization...WebORMException
- 036 Valid Sudoku
- spring - mvc - @ValidSpringMVC
- Longest Valid Parentheses
- DataTables 1.10錯誤: requested unknown parameter
- Rancher Dashboard 無法訪問 引申發現K8S報錯Unable to connect to the server: x509: certificate has expired or is not yet validK8SServer
- CSS E:targetCSS
- currentTarget VS target
- Leetcode 20 Valid ParenthesesLeetCode