根据文章:
我创建了 PKCS12 证书并将文件keystore.p12放在src/main/respurces
我的 Spring 启动应用程序运行良好,我可以访问我的休息服务。
从另一个弹簧启动应用程序,我做http请求:
ResponseEntity<byte[]> mappingTemplateResponseEntity = restTemplate.exchange(httpsUrl, HttpMethod.GET, new HttpEntity<>(new HttpHeaders()), byte[].class);
并且此代码会导致异常,因为证书未注册。
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://localhost:8801/stub_mapping_template": 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
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:666)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
at pack.MappingTemplateService.checkForUpdates(MappingTemplateService.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: 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:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
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)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:78)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652)
... 17 common frames omitted
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:387)
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:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
... 31 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 37 common frames omitted
根据我尝试输入的文章:
D:\app\src\main\resources>keytool -list -v -storetype pkcs12 -密钥库密钥库.p12 输入密钥库密码:
密钥库类型:PKCS12 密钥库提供程序:SunJSSE
您的密钥库包含 1 个条目
别名:雄猫 创建日期:2018 年 1 月 9 日 参赛类型: 私钥条目证书链长度:1 证书 1:所有者: CN=本地主机,OU=未知,O=未知,L=未知,ST=未知,C=未知 颁发者:CN=本地主机,OU=未知,O=未知,L=未知,ST=未知, C=未知 序列号: 64cd4d27 有效期自: 星期二 Jan 09 17:56:07 MSK 2018 年至: 周五 1月 07 日 17:56:07 MSK 2028 证书指纹: MD5: A6:F5:67:EE:87:65:21:62:50:5B:67:AE:63:F6:AE:C0 SHA1: B8:F5:F7:7D:8C:4C:90:0E:BA:CE:9D:22:3A:D3:A7:6E:BB:12:1B:D8 SHA256: 35:B5:DF:15:FC:3B:DD:D3:05:58:88:92:00:47:8F:62:2C:97:D7:20:77:FA:7D:55:00:64:E9:62:F4:7D:3B:08 签名算法名称:SHA256 与 RSA 版本: 3
扩展:
1:对象 ID:2.5.29.14 严重性=假 主题键标识符 [ 键标识符 [ 0000: 3E D4 2D F8 自动对焦 D2 C2 4E 51 4F 3E A4 01 FE E2
34>.-....NQO>....4 0010: 48 B0 5F 4F
H._O ]
看起来我不应该显式导出证书,因为我使用 PKCS12 证书。
如何修复我的错误?
我解决了我的问题:
-
注册豆:
@Value("${http.client.ssl.trust-store}") private Resource keyStore; @Value("${http.client.ssl.trust-store-password}") private String keyStorePassword; @Bean RestTemplate restTemplate() throws Exception { SSLContext sslContext = new SSLContextBuilder() .loadTrustMaterial( keyStore.getURL(), keyStorePassword.toCharArray() ).build(); SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext); HttpClient httpClient = HttpClients.custom() .setSSLSocketFactory(socketFactory).build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); return new RestTemplate(factory); }
2.添加到application.properties
:
# The format used for the keystore
server.ssl.key-store-type:PKCS12
# The path to the keystore containing the certificate
server.ssl.key-store=classpath:keystore.p12
# The password used to generate the certificate
server.ssl.key-store-password=password
# The alias mapped to the certificate
server.ssl.key-alias=tomcat
http.client.ssl.trust-store=classpath:keystore.p12
http.client.ssl.trust-store-password=password