Overview
当使用httpclinet发起https请求时报如下错误:
Javax.net.ssl.SSLHandshakeException:Received Fatal alert:handshake_failure at Com.sun.net.ssl.internal.ssl.Alerts.getSSLException (alerts.java:174) at Com.sun.net.ssl.internal.ssl.Alerts.getSSLException (alerts.java:136) at Com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert (sslsocketimpl.java:1657) at Com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord (sslsocketimpl.java:932) at Com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake (sslsocketimpl.java:1096) at Com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake (sslsocketimpl.java:1123) at Com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake (sslsocketimpl.java:1107) at Org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket (sslconnectionsocketfactory.java:261) at Org.apache.http.impl.conn.HttpClientConnectionOperator.connect (httpclientconnectionoperator.java:118) at Org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect (Poolinghttpclientconnectionmanager.java:314) at Org.apache.http.impl.execchain.MainClientExec.establishRoute (mainclientexec.java:357) at Org.apache.http.impl.execchain.MainClientExec.execute (mainclientexec.java:218) at Org.apache.http.impl.execchain.ProtocolExec.execute (protocolexec.java:194) at Org.apache.http.impl.execchain.RetryExec.execute (retryexec.java:85) at Org.apache.http.impl.execchain.RedirectExec.execute (redirectexec.java:108) at Org.apache.http.impl.client.InternalHttpClient.doExecute (internalhttpclient.java:186) at Org.apache.http.impl.client.CloseableHttpClient.execute (closeablehttpclient.java:82) at Org.apache.http.impl.client.CloseableHttpClient.execute (closeablehttpclient.java:106)
Reference URL not resolved
Access HTTPS, throw exception javax.net.ssl.SSLHandshakeException:Received fatal alert:handshake_failure
Use httpclient to send HTTPS requests and configure Tomcat to support SSL
The background of the analysis process
Since the certificate is self-signed, and reinforced, I believe many people will ask why the reinforcement, because if you do not reinforce HTTPS will not be accessible in the FF, the error is as follows:
Solution reference Tomcat6+jdk6 How to harden, solve logjam attack
Resolve process Analysis non-reinforcing whether direct access is possible
Tested for non-reinforcing condition access no problem
Cannot access cause analysis after reinforcement
Because the reinforcement is mainly specified protocols and ciphers, so whether the request can also specify protocols and ciphers, check the official documents found the following information
By setting protocols and ciphers before the httpclient request, the code is as follows:
System.setProperty("https.protocols", "与server.xml中的protocols一致"); System.setProperty("https.cipherSuites", "与server.xml中的ciphers一致");
Re-launch the request, find or error
Analyze whether the settings are in effect
Through the debug httpclinet under the Httpclientbuilder class source code found as follows
Add the following bold code:
Httpclients.custom (). usesystemproperties (). Setdefaultrequestconfig (Defaultrequestconfig). Setsslcontext (Sslcontext). Build () ;
Re-launch the request, find or error
Querying locally supported protocols and algorithms
The code is as follows:
public class Httpstest {public static void main (string[] args) {Sslcontext sc; try {sc = sslcontext.getinstance ("TLS"); Implement a X509trustmanager interface for bypassing validation without modifying the inside method X509trustmanager TrustManager = new X509trustmanager () { @Override public void checkclienttrusted (java.security.cert.x509certificate[] P Aramarrayofx509certificate, String paramstring) throws Certificateexception {} @Override public void checkservertrusted (java.security.cert.X509Certific Ate[] paramarrayofx509certificate, String paramstring) throws Certificateexception { } @Override Public java.security.cert.x509certificate[] Getacceptedissuers () { return null; } }; Sc.init (NULL, new trustmanager[] {TrustmanaGER}, NULL); SYSTEM.OUT.PRINTLN ("Default Secure Sockets used by protocol:" + Sc.getprotocol ()); Get Sslcontext instance related sslengine sslengine en = sc.createsslengine (); System.out. println ("Supported protocols:" + arrays.aslist (En.getsupportedprotocols ())); SYSTEM.OUT.PRINTLN ("Enabled protocol:" + Arrays.aslist (En.getenabledprotocols ())); SYSTEM.OUT.PRINTLN ("Supported cryptographic Suites:" + arrays.aslist (En.getsupportedciphersuites ())); SYSTEM.OUT.PRINTLN ("Encryption Suite enabled:" + arrays.aslist (En.getenabledciphersuites ())); } catch (Exception e) {//TODO auto-generated catch block E.printstacktrace (); }} and then set protocols and ciphers before the httpclient request,
System.setProperty("https.protocols", "其值为服务器和本地相同的"); System.setProperty("https.cipherSuites", "其值为服务器和本地相同的");
The request was re-initiated and the request succeeded.
Release Notes
httpclinet:4.3.1
jdk:1.6
Tomcat:6
HttpClient initiating the request code
访问 https://gitee.com/die/help_common.git中的httpclinet进行下载
Reference articles
HttpClient How to specify Ciphersuites
Log a fix httpcline request HTTPS handshake_failure error