I am using JDK 23, Spring Boot 3.4.1 . I create trust materials follow https://github.com/kirilarsov/mtls/blob/main/README.md and apply Spring Boot's SSLBundle feature (https://spring.io/blog/2023/06/07/securing-spring-boot-applications-with-ssl )
keytool -genkeypair -alias server -keyalg RSA -keysize 4096 -validity 365 -dname "CN=Server,OU=Server,O=Examples,L=,S=CA,C=U" -keypass changeit -keystore server.p12 -storeType PKCS12 -storepass changeit
keytool -genkeypair -alias client -keyalg RSA -keysize 4096 -validity 365 -dname "CN=Client,OU=Server,O=Examples,L=,S=CA,C=U" -keypass changeit -keystore client.p12 -storeType PKCS12 -storepass changeit
keytool -exportcert -alias client -file client.cer -keystore client.p12 -storepass changeit
keytool -exportcert -alias server -file server.cer -keystore server.p12 -storepass changeit
keytool -importcert -keystore client-truststore.p12 -alias server-public -file server.cer -storepass changeit -noprompt
keytool -importcert -keystore server-truststore.p12 -alias client-public -file client.cer -storepass changeit -noprompt
But when I use SSLBundle, I always catch error
javax.net.ssl|INFO|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.441 GMT+07:00|AlpnExtension.java:179|No available application protocols
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.441 GMT+07:00|SSLExtensions.java:272|Ignore, context unavailable extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.441 GMT+07:00|SessionTicketExtension.java:352|Stateless resumption supported
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.442 GMT+07:00|SSLExtensions.java:272|Ignore, context unavailable extension: cookie
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.539 GMT+07:00|SSLExtensions.java:272|Ignore, context unavailable extension: renegotiation_info
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.540 GMT+07:00|PreSharedKeyExtension.java:659|No session to resume.
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.540 GMT+07:00|SSLExtensions.java:272|Ignore, context unavailable extension: pre_shared_key
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.544 GMT+07:00|ClientHello.java:638|Produced ClientHello handshake message (
"ClientHello": {
"client version" : "TLSv1.2",
"random" : "E77AF343A88EC48D9F25215023BB546C7869E14F62486BB251DFBEFCC559C957",
"session id" : "711B47572621C39B1CA004852D4B8AEA3842721A552DD9DA68539EA0667DB0E9",
"cipher suites" : "[TLS_AES_256_GCM_SHA384(0x1302), TLS_AES_128_GCM_SHA256(0x1301), TLS_CHACHA20_POLY1305_SHA256(0x1303), TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(0xC02C), TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(0xC02B), TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256(0xCCA9), TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xC030), TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256(0xCCA8), TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(0xC02F), TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(0x009F), TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256(0xCCAA), TLS_DHE_DSS_WITH_AES_256_GCM_SHA384(0x00A3), TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(0x009E), TLS_DHE_DSS_WITH_AES_128_GCM_SHA256(0x00A2), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384(0xC024), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384(0xC028), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256(0xC023), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256(0xC027), TLS_DHE_RSA_WITH_AES_256_CBC_SHA256(0x006B), TLS_DHE_DSS_WITH_AES_256_CBC_SHA256(0x006A), TLS_DHE_RSA_WITH_AES_128_CBC_SHA256(0x0067), TLS_DHE_DSS_WITH_AES_128_CBC_SHA256(0x0040), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(0xC00A), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(0xC014), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA(0xC009), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(0xC013), TLS_DHE_RSA_WITH_AES_256_CBC_SHA(0x0039), TLS_DHE_DSS_WITH_AES_256_CBC_SHA(0x0038), TLS_DHE_RSA_WITH_AES_128_CBC_SHA(0x0033), TLS_DHE_DSS_WITH_AES_128_CBC_SHA(0x0032), TLS_RSA_WITH_AES_256_GCM_SHA384(0x009D), TLS_RSA_WITH_AES_128_GCM_SHA256(0x009C), TLS_RSA_WITH_AES_256_CBC_SHA256(0x003D), TLS_RSA_WITH_AES_128_CBC_SHA256(0x003C), TLS_RSA_WITH_AES_256_CBC_SHA(0x0035), TLS_RSA_WITH_AES_128_CBC_SHA(0x002F), TLS_EMPTY_RENEGOTIATION_INFO_SCSV(0x00FF)]",
"compression methods" : "00",
"extensions" : [
"server_name (0)": {
type=host_name (0), value=Server
},
"status_request (5)": {
"certificate status type": ocsp
"OCSP status request": {
"responder_id": <empty>
"request extensions": {
<empty>
}
}
},
"supported_groups (10)": {
"named groups": [x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
},
"ec_point_formats (11)": {
"formats": [uncompressed]
},
"status_request_v2 (17)": {
"cert status request": {
"certificate status type": ocsp_multi
"OCSP status request": {
"responder_id": <empty>
"request extensions": {
<empty>
}
}
}
},
"extended_master_secret (23)": {
<empty>
},
"session_ticket (35)": {
<empty>
},
"signature_algorithms (13)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, ed25519, ed448, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
},
"supported_versions (43)": {
"versions": [TLSv1.3, TLSv1.2]
},
"psk_key_exchange_modes (45)": {
"ke_modes": [psk_dhe_ke]
},
"signature_algorithms_cert (50)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, ed25519, ed448, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
},
"key_share (51)": {
"client_shares": [
{
"named group": x25519
"key_exchange": {
0000: F4 CE 71 61 2C DF B8 F3 B7 4B FE DB AD BA 2C 36 ..qa,....K....,6
0010: 82 D9 C0 24 C8 E1 F1 B0 AB 9B 9E 41 F9 F4 85 78 ...$.......A...x
}
},
{
"named group": secp256r1
"key_exchange": {
0000: 04 57 EA 73 91 49 E3 54 40 19 77 63 A0 D9 08 7E .W.s.I.T@.wc....
0010: E9 88 28 B4 C9 F3 DE 90 71 80 1A 82 7E 49 88 3D ..(.....q....I.=
0020: 82 34 62 A4 44 C6 F7 CA 37 7E 7E 84 89 83 DF 1C .4b.D...7.......
0030: 05 D8 64 3C 20 C4 FB EA 06 40 BB D9 E7 A8 59 10 ..d< ....@....Y.
0040: E6
}
},
]
}
]
}
)
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.630 GMT+07:00|ServerHello.java:892|Consuming ServerHello handshake message (
"ServerHello": {
"server version" : "TLSv1.2",
"random" : "385B3637216A5EE39A33137C69C5D3F2037F524AC254CB4CED53FE4B87D3DC3D",
"session id" : "711B47572621C39B1CA004852D4B8AEA3842721A552DD9DA68539EA0667DB0E9",
"cipher suite" : "TLS_AES_256_GCM_SHA384(0x1302)",
"compression methods" : "00",
"extensions" : [
"supported_versions (43)": {
"selected version": [TLSv1.3]
},
"key_share (51)": {
"server_share": {
"named group": x25519
"key_exchange": {
0000: 50 FF BB 0F 35 37 8C 80 8E 3B D4 48 23 4E FD F9 P...57...;.H#N..
0010: 3C 15 84 15 35 28 D9 39 49 2B FB 87 DD 6F 57 6D <...5(.9I+...oWm
}
},
}
]
}
)
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.630 GMT+07:00|SSLExtensions.java:204|Consumed extension: supported_versions
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.630 GMT+07:00|ServerHello.java:988|Negotiated protocol version: TLSv1.3
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.631 GMT+07:00|SSLExtensions.java:175|Ignore unsupported extension: server_name
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.631 GMT+07:00|SSLExtensions.java:175|Ignore unsupported extension: max_fragment_length
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.631 GMT+07:00|SSLExtensions.java:175|Ignore unsupported extension: status_request
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.631 GMT+07:00|SSLExtensions.java:175|Ignore unsupported extension: ec_point_formats
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.631 GMT+07:00|SSLExtensions.java:175|Ignore unsupported extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.631 GMT+07:00|SSLExtensions.java:175|Ignore unsupported extension: status_request_v2
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.631 GMT+07:00|SSLExtensions.java:175|Ignore unsupported extension: extended_master_secret
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.632 GMT+07:00|SSLExtensions.java:175|Ignore unsupported extension: session_ticket
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.632 GMT+07:00|SSLExtensions.java:204|Consumed extension: supported_versions
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.633 GMT+07:00|SSLExtensions.java:204|Consumed extension: key_share
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.633 GMT+07:00|SSLExtensions.java:175|Ignore unsupported extension: renegotiation_info
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.633 GMT+07:00|PreSharedKeyExtension.java:922|Handling pre_shared_key absence.
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.633 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: server_name
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.633 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: max_fragment_length
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.633 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: status_request
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.633 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: ec_point_formats
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.634 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.634 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: status_request_v2
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.634 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: extended_master_secret
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.634 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: session_ticket
javax.net.ssl|WARNING|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.634 GMT+07:00|SSLExtensions.java:227|Ignore impact of unsupported extension: supported_versions
javax.net.ssl|WARNING|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.634 GMT+07:00|SSLExtensions.java:227|Ignore impact of unsupported extension: key_share
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.634 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: renegotiation_info
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.634 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: pre_shared_key
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.639 GMT+07:00|SSLCipher.java:1836|KeyLimit read side: algorithm = AES/GCM/NoPadding:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.639 GMT+07:00|SSLCipher.java:1987|KeyLimit write side: algorithm = AES/GCM/NoPadding:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.640 GMT+07:00|ChangeCipherSpec.java:244|Consuming ChangeCipherSpec message
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.643 GMT+07:00|EncryptedExtensions.java:172|Consuming EncryptedExtensions handshake message (
"EncryptedExtensions": [
"supported_groups (10)": {
"named groups": [x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
}
]
)
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.643 GMT+07:00|SSLExtensions.java:185|Ignore unavailable extension: server_name
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.643 GMT+07:00|SSLExtensions.java:185|Ignore unavailable extension: max_fragment_length
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.643 GMT+07:00|SSLExtensions.java:204|Consumed extension: supported_groups
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.643 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: server_name
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.643 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: max_fragment_length
javax.net.ssl|WARNING|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.644 GMT+07:00|SSLExtensions.java:227|Ignore impact of unsupported extension: supported_groups
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.644 GMT+07:00|SSLExtensions.java:219|Ignore unavailable extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.644 GMT+07:00|CertificateRequest.java:974|Consuming CertificateRequest handshake message (
"CertificateRequest": {
"certificate_request_context": "",
"extensions": [
"signature_algorithms (13)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, ed25519, ed448, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, ecdsa_sha1, rsa_pkcs1_sha1]
},
"certificate_authorities (47)": {
"certificate authorities": [
CN=Client, OU=Server, O=Examples, L=, ST=CA, C=U]
},
"signature_algorithms_cert (50)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, ed25519, ed448, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, ecdsa_sha1, rsa_pkcs1_sha1]
}
]
}
)
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.644 GMT+07:00|SSLExtensions.java:204|Consumed extension: signature_algorithms
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.644 GMT+07:00|SSLExtensions.java:204|Consumed extension: certificate_authorities
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.645 GMT+07:00|SSLExtensions.java:204|Consumed extension: signature_algorithms_cert
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.645 GMT+07:00|SSLExtensions.java:236|Populated with extension: signature_algorithms
javax.net.ssl|WARNING|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.645 GMT+07:00|SSLExtensions.java:227|Ignore impact of unsupported extension: certificate_authorities
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.645 GMT+07:00|SSLExtensions.java:236|Populated with extension: signature_algorithms_cert
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.646 GMT+07:00|CertificateMessage.java:1143|Consuming server Certificate handshake message (
"Certificate": {
"certificate_request_context": "",
"certificate_list": [
{
"certificate" : {
"version" : "v3",
"serial number" : "00:fe:0f:1d:85:55:76:f1:12",
"signature algorithm": "SHA384withRSA",
"issuer" : "CN=Server, OU=Server, O=Examples, L=, ST=CA, C=U",
"not before" : "2025-01-09 11:57:07.000 GMT+07:00",
"not after" : "2026-01-09 11:57:07.000 GMT+07:00",
"subject" : "CN=Server, OU=Server, O=Examples, L=, ST=CA, C=U",
"subject public key" : "RSA",
"extensions" : [
{
ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 9D FB 7F 8F 60 53 4C A7 0B 4E E0 A7 A7 D2 97 9A ....`SL..N......
0010: 44 AD E6 84 D...
]
]
}
]}
"extensions": {
<no extension>
}
},
]
}
)
javax.net.ssl|DEBUG|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.646 GMT+07:00|SSLExtensions.java:185|Ignore unavailable extension: status_request
javax.net.ssl|ERROR|E4|HttpClient-1-Worker-1|2025-01-09 17:24:11.652 GMT+07:00|TransportContext.java:375|Fatal (CERTIFICATE_UNKNOWN): PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target (
"throwable" : {
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:388)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:271)
at java.base/sun.security.validator.Validator.validate(Validator.java:256)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:284)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:144)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1304)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1203)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1146)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:393)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:476)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1274)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1260)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1205)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1597)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.lambda$executeTasks$3(SSLFlowDelegate.java:1148)
at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:178)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.executeTasks(SSLFlowDelegate.java:1143)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.doHandshake(SSLFlowDelegate.java:1109)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:508)
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:283)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1575)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:148)
at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:129)
at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:383)
... 26 more}
)
Can Spring Boot's SSLBundle work with certificates without CA (just mutual authenticated, not CA)?
It is possible to have mutual tls without ca I think you are in the right direction, but missing some key parts in the command which is resulting you in having this issue.
I have the following commands which should do the trick for you.
Create the server identity
keytool -v -genkeypair -dname "CN=Server,OU=Server,O=Examples,L=,S=CA,C=U" -keystore server-identity.p12 -storepass secret -keypass secret -keyalg RSA -keysize 2048 -alias server -validity 3650 -deststoretype pkcs12 -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth -ext SubjectAlternativeName:c=DNS:localhost,IP:127.0.0.1
Create the client identity
keytool -v -genkeypair -dname "CN=Client,OU=Server,O=Examples,L=,S=CA,C=U" -keystore client-identity.p12 -storepass secret -keypass secret -keyalg RSA -keysize 2048 -alias client -validity 3650 -deststoretype pkcs12 -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth
Export certificate of the server
keytool -v -exportcert -file server.cer -alias server -keystore server-identity.p12 -storepass secret -rfc
Export certificate of the client
keytool -v -exportcert -file client.cer -alias client -keystore client-identity.p12 -storepass secret -rfc
Create the server truststore with the certificate of the client
keytool -v -importcert -file client.cer -alias client -keystore server-truststore.p12 -storepass secret -noprompt
Create the client truststore with the certificate of the server
keytool -v -importcert -file server.cer -alias server -keystore client-truststore.p12 -storepass secret -noprompt
I think the main difference in the commands which I have used is the extension part, which is -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth
other than that it looks quite similar.
Can you retry with the above steps and share your results?
Also here you can find some more information about these steps and a working example which I have built myself: https://github.com/Hakky54/mutual-tls-ssl