在本地环境调用远程接口正常,当部署到Linux测试环境后出现如下错误。
org.springframework.web.client.ResourceAccessException: I/O error on GET request for “https://www.***.com/***”: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is 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
这是因为没有接入站点的证书
生成证书
import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class InstallCert {
public static void main(String[] args) throws Exception {
args = new String[]{"www.baidu.cn"}; //这样写入参数就可以直接在IDE中直接运行main方法
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);
}
}
}
运行main方法,出现如下信息
Loading KeyStore D:\java_software\jdk1.8\jdk\jre\lib\security\cacerts...
Opening connection to www.jisilu.cn:443...
Starting SSL handshake...
javax.net.ssl.SSLException: java.lang.UnsupportedOperationException
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1906)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1889)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1410)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at me.zhengjie.InstallCert.main(InstallCert.java:64)
Caused by: java.lang.UnsupportedOperationException
at me.zhengjie.InstallCert$SavingTrustManager.getAcceptedIssuers(InstallCert.java:149)
at sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(SSLContextImpl.java:1097)
at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:1043)
at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:985)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
... 2 more
Server sent 2 certificate(s):
1 Subject CN=www.jisilu.cn
Issuer CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
sha1 dd e8 85 37 74 9c 46 56 1a 52 da 2a 10 a2 03 4f 75 ea 16 d2
md5 2e 22 8e 11 01 33 af 2a 24 0f e0 93 87 21 33 e2
2 Subject CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
Issuer CN=DST Root CA X3, O=Digital Signature Trust Co.
sha1 e6 a3 b4 5b 06 2d 50 9b 33 82 28 2d 19 6e fe 97 d5 95 6c cb
md5 b1 54 09 27 4f 54 ad 8f 02 3d 3b 85 a5 ec ec 5d
Enter certificate to add to trusted keystore or 'q' to quit: [1]
输入1,回车
1
[
[
Version: V3
Subject: CN=www.jisilu.cn
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
modulus: 25753959587506117051999349562691606169983982704882542671730556621339328864259500250916896426225279358989591890651580220372917504458884474586742586470290808473168786888493596073194891722593119967026554836631066350337587065618240062544661568447476811249005057407747989659454040880445306406126169991113341783807027166331525252964272024210992535978688644496662139434388321031279473617977642559269552631038634261474188665391044360252036545082468349088352133868950739258737826619537326613961040023099114236155181660628690144562238130975677137190261332287661468623644138849162650209317037947652070284614614366466782015891999
public exponent: 65537
Validity: [From: Fri Jul 10 23:07:27 CST 2020,
To: Thu Oct 08 23:07:27 CST 2020]
Issuer: CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
SerialNumber: [ 031ed9cd b093786d 50c8b54f 9105277e f3ea]
Certificate Extensions: 9
[1]: ObjectId: 1.3.6.1.4.1.11129.2.4.2 Criticality=false
Extension unknown: DER encoded OCTET string =
0000: 04 81 F5 04 81 F2 00 F0 00 76 00 F0 95 A4 59 F2 .........v....Y.
0010: 00 D1 82 40 10 2D 2F 93 88 8E AD 4B FE 1D 47 E3 ...@.-/....K..G.
0020: 99 E1 D0 34 A6 B0 A8 AA 8E B2 73 00 00 01 73 39 ...4......s...s9
0030: 7B 46 BD 00 00 04 03 00 47 30 45 02 21 00 D8 99 .F......G0E.!...
0040: 5D D2 BE 97 F5 50 5A 5C 4A 59 92 7C 00 E1 95 53 ]....PZ\JY.....S
0050: 1D A8 F7 C0 9C 35 3C AC 15 0E AB 91 0A F8 02 20 .....5<........
0060: 4F A4 FE F0 C7 CB 16 5B 2F 59 DE 50 AD 6A B1 AA O......[/Y.P.j..
0070: 37 77 62 57 B8 35 2F B1 01 80 07 F9 6A E8 1F 29 7wbW.5/.....j..)
0080: 00 76 00 B2 1E 05 CC 8B A2 CD 8A 20 4E 87 66 F9 .v......... N.f.
0090: 2B B9 8A 25 20 67 6B DA FA 70 E7 B2 49 53 2D EF +..% gk..p..IS-.
00A0: 8B 90 5E 00 00 01 73 39 7B 46 BB 00 00 04 03 00 ..^...s9.F......
00B0: 47 30 45 02 21 00 A1 21 AC E1 27 81 D4 FC 79 C9 G0E.!..!..'...y.
00C0: E6 25 3E 1F AC B5 7A 38 CB F7 1C 95 28 22 18 A7 .%>...z8....("..
00D0: 63 EF 7B BF CF 05 02 20 37 98 04 06 29 8C 92 A2 c...... 7...)...
00E0: FC F0 83 AC 80 E8 A4 D5 EF D9 93 19 52 03 7C BA ............R...
00F0: 07 D7 64 5E 17 74 03 06 ..d^.t..
[2]: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
[
accessMethod: ocsp
accessLocation: URIName: http://ocsp.int-x3.letsencrypt.org
,
accessMethod: caIssuers
accessLocation: URIName: http://cert.int-x3.letsencrypt.org/
]
]
[3]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: A8 4A 6A 63 04 7D DD BA E6 D1 39 B7 A6 45 65 EF .Jjc......9..Ee.
0010: F3 A8 EC A1 ....
]
]
[4]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:false
PathLen: undefined
]
[5]: ObjectId: 2.5.29.32 Criticality=false
CertificatePolicies [
[CertificatePolicyId: [2.23.140.1.2.1]
[] ]
[CertificatePolicyId: [1.3.6.1.4.1.44947.1.1.1]
[PolicyQualifierInfo: [
qualifierID: 1.3.6.1.5.5.7.2.1
qualifier: 0000: 16 1A 68 74 74 70 3A 2F 2F 63 70 73 2E 6C 65 74 ..http://cps.let
0010: 73 65 6E 63 72 79 70 74 2E 6F 72 67 sencrypt.org
]] ]
]
[6]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
serverAuth
clientAuth
]
[7]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_Encipherment
]
[8]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
DNSName: www.jisilu.cn
]
[9]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 06 70 79 C8 65 A5 3C 95 3B FD 8B 06 70 82 D0 FB .py.e.<.;...p...
0010: 59 D5 6C B4 Y.l.
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 5A 3C A8 72 46 CD BC A6 B5 0F 53 4F E0 B4 C0 F2 Z<.rF.....SO....
0010: B3 8E 12 DE 9B 32 D0 D2 CD 01 5A 54 55 16 5B 2B .....2....ZTU.[+
0020: 88 50 DA 29 AD 97 7B 73 0F 41 D9 98 BB BA E7 31 .P.)...s.A.....1
0030: B2 B2 D2 E8 34 44 34 E5 FB 73 3D 34 B9 65 45 AA ....4D4..s=4.eE.
0040: 38 AE 4F EF 3F 5A 7E 8D A6 78 BD 52 DD 57 1C F7 8.O.?Z...x.R.W..
0050: C2 71 0D A2 BC 65 8A 25 7D E5 23 1D 85 72 6F 6A .q...e.%..#..roj
0060: 45 F1 85 04 4D A3 53 88 5F 38 E1 E7 C8 BE DC E6 E...M.S._8......
0070: BD C6 77 59 5A 95 4A 6E DE 12 FA 5E D3 C0 2D F4 ..wYZ.Jn...^..-.
0080: 0F 8E AE 29 0B 3F 99 B1 20 C7 0E 7A 67 68 0E FD ...).?.. ..zgh..
0090: 65 1E 3A E4 6A 62 44 22 97 63 0F AE 06 E5 70 EB e.:.jbD".c....p.
00A0: B5 0C CF D6 C0 A5 25 51 CF CE BD 36 6E 1C DB 58 ......%Q...6n..X
00B0: CC E8 92 17 F6 6E D7 2A 75 6B F1 55 CA 43 F2 C8 .....n.*uk.U.C..
00C0: 2D 7E F9 FB 69 6C 80 14 6F 9D 89 8D D0 E9 0F 5D -...il..o......]
00D0: 6C CD 29 77 9C B6 23 9B 94 BD 57 7A 35 81 9E 1B l.)w..#...Wz5...
00E0: 64 7B C3 D2 49 F2 19 26 04 6F 47 99 03 B2 0F 98 d...I..&.oG.....
00F0: 47 98 1A 13 4D 40 A5 F2 F4 A7 93 CA B0 01 9F A8 G...M@..........
]
Added certificate to keystore 'jssecacerts' using alias 'www.jisilu.cn-1'
Process finished with exit code 0
生成jssecacerts文件成功。
导入证书
把jssecacerts文件拷贝到Linux上的java目录 **/jdk1.8.0_11/jre/lib/security下。重启项目就可以正常访问了。