gpt4 book ai didi

java - 仅在使用 RestTemplate 时出现 SSLHandshakeException

转载 作者:行者123 更新时间:2023-12-04 22:38:37 25 4
gpt4 key购买 nike

我正在使用 Java 8,尝试发布 https 第三方(其他子域作品),与 postman 合作,但使用 RestTemplate抛出 SSLHandshakeException

new RestTemplate().postForEntity("https://external-host.com" ,new HttpEntity<>(null, new HttpHeaders()), String.class);
我在 jdk1.8.0_151\jre\lib\security\policy\unlimited 文件夹中有 JCE Unlimited jars,并且我有弹性城堡 bcpkix-jdk15on 和 bcprov-jdk15on 版本 1.55
异常(exception):
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://external-host.com": Received fatal alert: handshake_failure; nested exception is javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:785)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:468)
...
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
SSLConnectionSocketFactory.java:353
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141)
DefaultHttpClientConnectionOperator.java:141
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
PoolingHttpClientConnectionManager.java:353
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
MainClientExec.java:380
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
MainClientExec.java:236
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
ProtocolExec.java:184
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
RetryExec.java:88
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
RedirectExec.java:110
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
InternalHttpClient.java:184
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
CloseableHttpClient.java:82
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
CloseableHttpClient.java:55
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
HttpComponentsClientHttpRequest.java:87
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
AbstractBufferingClientHttpRequest.java:48
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
AbstractClientHttpRequest.java:66
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:776)
RestTemplate.java:776
... 42 more
使用其他 solutions 的相同输出将 RestTemplate 配置为:
TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());

SSL 日志:
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie: GMT: 1645533027 bytes = { 229, 64, 215, 234, 240, 91, 46, 176, 144, 108, 104, 176, 6, 192, 147, 200, 69, 213, 196, 106, 125, 235, 5, 167, 51, 215, 144, 174 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Extension server_name, server_name: [type=host_name (0), value=external-host.com]
***
ajp-nio-8009-exec-32, WRITE: TLSv1.2 Handshake, length = 211
ajp-nio-8009-exec-32, READ: TLSv1.2 Alert, length = 2
ajp-nio-8009-exec-32, RECV TLSv1.2 ALERT: fatal, handshake_failure
ajp-nio-8009-exec-32, called closeSocket()
ajp-nio-8009-exec-32, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
08:42:43.535 [ajp-nio-8009-exec-32] TRACE o.s.web.servlet.DispatcherServlet - Failed to complete request
编辑 我下载 cer来自站点的文件,添加到 Java 的 cacerts 并创建 p12 文件,并尝试使用以下代码,但仍然握手异常
KeyStore clientStore = KeyStore.getInstance("PKCS12");
clientStore.load(new FileInputStream(utils.getStoreProperty("./external.p12")),
"MYPASS".toCharArray());

SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
sslContextBuilder.useProtocol("TLSv1.2");
sslContextBuilder.loadKeyMaterial(clientStore, "MYPASS".toCharArray());
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
sslContextBuilder.loadTrustMaterial(null, acceptingTrustStrategy);
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build());
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();

openssl s_client -connect host:443 的以下输出按照建议
@dave_thompson_085,@yan
WARNING: can't open config file: /usr/local/ssl/openssl.cnf
CONNECTED(000001A4)
depth=3 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify error:num=19:self signed certificate in certificate chain
---
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5814 bytes and written 433 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: A4966A2268EE5CCFA25DEE734DC980D01DF40A4763A4DF3CD19ADA49FF9AD90E
Session-ID-ctx:
Master-Key: 58BE6AF39E3DB3CBF3166A286550F2333028E66A9CC59AE886EAA777BAEA82A21D318E89746B97B1BFE0E3E7BF60F5E1
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 25 c2 24 26 c2 8f d1 6d-32 5e 2f f6 40 95 af d6 %.$&...m2^/.@...
0010 - 02 de 28 3e 34 ae 47 96-2c 6a 87 2e 61 e6 fd a2 ..(>4.G.,j..a...
0020 - 75 3b 3c 3b b2 ee 3c 16-ba e5 49 1c 18 f6 a1 16 u;<;..<...I.....
0030 - e3 4e 7b 6f 48 5d e7 e3-03 df c5 86 45 81 12 5b .N{oH]......E..[
0040 - 4e d7 27 da f5 cd ed 18-6d 41 00 55 7a 8e 62 54 N.'.....mA.Uz.bT
0050 - 31 75 90 3c aa 2a f9 2b-51 c2 c0 10 5d ca 02 6f 1u.<.*.+Q...]..o
0060 - 51 0e e0 62 6d 94 12 bd-85 4b 01 88 dc 5d 90 ad Q..bm....K...]..
0070 - 30 53 8c 09 a7 01 d9 d7-1b 89 ec 77 35 93 9f ae 0S.........w5...
0080 - b1 00 c7 ba 1c ea 84 77-36 bf 58 59 7a 78 44 f2 .......w6.XYzxD.
0090 - 77 55 f4 41 2b dd 3c 54-02 38 ae 37 ec 8a c6 10 wU.A+.<T.8.7....
00a0 - 6e d5 23 0a 05 5c 19 9f-02 4d 9a 0a 1c 9a be 2e n.#..\...M......

Start Time: 1645945411
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
编辑 我关注了@taleb answer ,但仍然存在相同的握手异常

Add the bcprov-.jar to /usr/lib/jvm/jre/lib/ext


Edit /usr/lib/jvm/jre/lib/security/java.security adding the following line to the list of providers:


security.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider

(I added it as the 6th entry but you can add higher in the order if you prefer)


重新启动我的应用程序

最佳答案

请注意,调试输出中描述的密码套件并未显示 openssl 实际使用的密码套件。 , ECDHE-RSA-AES256-GCM-SHA384 .事实上,它们不包括任何需要 AES 256 的密码套件。它可能不相关,但它可能是任何错误配置的症状,并且可以解释握手失败的原因。如Oracle documentation 中所示在描述 Java 8 支持的密码套件时:

Cipher suites that use AES_256 require installation of the JCEUnlimited Strength Jurisdiction Policy Files.


因此,请确保您安装并正确配置了 JCE Unlimited Strength Jurisdiction Policy Files .
正如@dave_thompson_085 在他的优秀评论中指出的那样,只有低于 8u161 的 Oracle Java 8 需要添加无限策略,如 Appendix C 中所述。上述 Oracle 文档。
JCE Unlimited Strength Jurisdiction Policy Files 自 JDK 8u151 起捆绑到 JDK 中。 ,但 unlimited策略未定义为 the default one从 JDK 8u161 开始。
在 JDK 8u151 或 8u152 中,如 one 中所述之前引用的链接,@dave_thompson_085 也解释了 - 再次非常感谢您,为了使 unlimited应该使用的JCE版本,需要定义系统属性 crypto.policy .从文档:

This release introduces a new feature whereby the JCE jurisdictionpolicy files used by the JDK can be controlled via a new Securityproperty. In older releases, JCE jurisdiction files had to bedownloaded and installed separately to allow unlimited cryptographyto be used by the JDK. The download and install steps are no longernecessary. To enable unlimited cryptography, one can use the newcrypto.policy Security property. If the new Security property(crypto.policy) is set in the java.security file, or has beenset dynamically by using the Security.setProperty() call beforethe JCE framework has been initialized, that setting will behonored. By default, the property will be undefined. If theproperty is undefined and the legacy JCE jurisdiction files don'texist in the legacy lib/security directory, then the defaultcryptographic level will remain at 'limited'. To configure the JDKto use unlimited cryptography, set the crypto.policy to a valueof 'unlimited'. See the notes in the java.security file shippingwith this release for more information.


OpenJDK 中不存在此问题。
作为替代解决方案,如 this related SO question 中所建议的那样,可能使用像 BouncyCaSTLe 这样的替代提供商也会有所帮助。

关于java - 仅在使用 RestTemplate 时出现 SSLHandshakeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71222498/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com