Spring Boot Webflux WebClient经HTTP代理双向TLS认证失败
HTTP代理下双向TLS认证握手失败问题
我有一个基于Spring Boot、Webflux的Java应用,使用搭载Reactor连接器的WebClient向外部服务器发起HTTPS请求。该服务器要求双向TLS认证,无代理时已通过配置SslContext实现正常运行,但配置HTTP代理(测试过tinyproxy和squid)后出现SSL握手错误。
无代理时正常运行的WebClient代码
String keystore = Files.readString(Paths.get("/my-keystore.p12")); InputStream keystoreInputStream = new ByteArrayInputStream(keystore); KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(keystoreInputStream, "keystore-pass"); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, "my-pass"); SslContext sslContext = SslContextBuilder.forClient() .keyManager(keyManagerFactory) .build(); WebClient.Builder builder = WebClient.builder() .baseUrl("external-service-url") .clientConnector( new ReactorClientHttpConnector( HttpClient.create() .secure(sslSpec -> sslSpec.sslContext(sslContext)) .proxy( proxySpec -> proxySpec .type(ProxyProvider.Proxy.HTTP) .host("my-proxy-host") .port(Integer.parseInt("3128")) ) ) );
无代理时关键SSL日志(开启-Djavax.net.debug=all)
javax.net.ssl|WARNING|10 51|reactor-http-epoll-5|2024-06-03 15:07:30.250 CEST|SignatureScheme.java:434|Unsupported signature scheme: dsa_sha384 javax.net.ssl|WARNING|10 51|reactor-http-epoll-5|2024-06-03 15:07:30.250 CEST|SignatureScheme.java:434|Unsupported signature scheme: dsa_sha512 javax.net.ssl|DEBUG|10 51|reactor-http-epoll-5|2024-06-03 15:07:30.250 CEST|SunX509KeyManagerImpl.java:388|matching alias: my-cert
启用代理后的关键SSL日志
javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.166 CEST|SignatureScheme.java:434|Unsupported signature scheme: dsa_sha384 javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.166 CEST|SignatureScheme.java:434|Unsupported signature scheme: dsa_sha512 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.166 CEST|X509Authentication.java:249|No X.509 cert selected for RSA javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.166 CEST|CertificateRequest.java:821|Unavailable authentication scheme: rsa_pkcs1_sha256 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.166 CEST|X509Authentication.java:249|No X.509 cert selected for DSA javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.166 CEST|CertificateRequest.java:821|Unavailable authentication scheme: dsa_sha256 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|X509Authentication.java:249|No X.509 cert selected for EC javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|CertificateRequest.java:821|Unavailable authentication scheme: ecdsa_secp256r1_sha256 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|X509Authentication.java:249|No X.509 cert selected for RSA javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|CertificateRequest.java:821|Unavailable authentication scheme: rsa_pkcs1_sha384 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|X509Authentication.java:249|No X.509 cert selected for EC javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|CertificateRequest.java:821|Unavailable authentication scheme: ecdsa_secp384r1_sha384 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|X509Authentication.java:249|No X.509 cert selected for RSA javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|CertificateRequest.java:821|Unavailable authentication scheme: rsa_pkcs1_sha512 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|X509Authentication.java:249|No X.509 cert selected for EC javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|CertificateRequest.java:821|Unavailable authentication scheme: ecdsa_secp521r1_sha512 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|X509Authentication.java:249|No X.509 cert selected for RSA javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|CertificateRequest.java:821|Unavailable authentication scheme: rsa_pkcs1_sha1 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|X509Authentication.java:249|No X.509 cert selected for DSA javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|CertificateRequest.java:821|Unavailable authentication scheme: dsa_sha1 javax.net.ssl|ALL|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|X509Authentication.java:249|No X.509 cert selected for EC javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|CertificateRequest.java:821|Unavailable authentication scheme: ecdsa_sha1 javax.net.ssl|WARNING|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|CertificateRequest.java:831|No available authentication scheme javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|SSLEngineInputRecord.java:176|Raw read ( 0000: XXXXXXXXXX ......... ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.167 CEST|SSLEngineInputRecord.java:213|READ: TLSv1.2 handshake, length = 4 javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.168 CEST|ServerHelloDone.java:151|Consuming ServerHelloDone handshake message ( <empty> ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.168 CEST|CertificateMessage.java:299|No X.509 certificate for client authentication, use empty Certificate message instead javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.168 CEST|CertificateMessage.java:330|Produced client Certificate handshake message ( "Certificates": <empty list> ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.171 CEST|ECDHClientKeyExchange.java:407|Produced ECDHE ClientKeyExchange handshake message ( "ECDH ClientKeyExchange": { "ecdh public": { XXXXXXX . }, } ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.175 CEST|ChangeCipherSpec.java:115|Produced ChangeCipherSpec message javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.175 CEST|Finished.java:396|Produced client Finished handshake message ( "Finished": { "verify data": { 0000: XXXXXXX }' } ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.175 CEST|SSLEngineOutputRecord.java:530|WRITE: TLSv1.2 handshake, length = 77 javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.176 CEST|SSLEngineOutputRecord.java:551|Raw write ( 0000: XXXXXX .. ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.176 CEST|SSLEngineOutputRecord.java:530|WRITE: TLSv1.2 change_cipher_spec, length = 1 javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.176 CEST|SSLEngineOutputRecord.java:551|Raw write ( 0000: XXXXXXX ...... ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.176 CEST|SSLEngineOutputRecord.java:530|WRITE: TLSv1.2 handshake, length = 16 javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.176 CEST|SSLCipher.java:1773|Plaintext before ENCRYPTION ( 0000: XXXXX ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.176 CEST|SSLEngineOutputRecord.java:551|Raw write ( 0000: XXXXX ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.218 CEST|SSLEngineInputRecord.java:176|Raw read ( 0000: XXXXXXX ......( ) javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.218 CEST|SSLEngineInputRecord.java:213|READ: TLSv1.2 alert, length = 2 javax.net.ssl|DEBUG|10 01|reactor-http-epoll-5|2024-06-03 15:05:32.219 CEST|Alert.java:238|Received alert message ( "Alert": { "level" : "fatal", "description": "handshake_failure" } )
从日志能看出,启用代理后JVM找不到用于认证的证书,但不清楚具体原因,也不确定HTTP代理环境下是否支持双向TLS认证这种方式。
内容的提问来源于stack exchange,提问作者Benoit
相关产品推荐
相关产品推荐

