如何强制客户端信任 PKCS12 证书(找不到请求目标的有效证书路径)?



根据文章:

我创建了 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 证书。

如何修复我的错误?

我解决了我的问题:

  1. 注册豆:

    @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

相关内容

最新更新