账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    java SSL连接异常 Remote host closed connection during handshake
    110
    0

    背景

    目前项目需要,利用java模拟登录一个https的网站

    • jdk 1.8
    • httpClient 4.5.2

    报错信息如下:

    main, received EOFException: error
    main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    main, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
    main, WRITE: TLSv1.2 Alert, length = 2
    [Raw write]: length = 7
    0000: 15 03 03 00 02 02 28                               ......(
    main, called closeSocket()
    Exception in thread "main" javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1002)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
        at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
        at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
        at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141)
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
        at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
        at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
        at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
        at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
        at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
        at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
        at newSpider.HttpTest.main(HttpTest.java:49)
    Caused by: java.io.EOFException: SSL peer shut down incorrectly
        at sun.security.ssl.InputRecord.read(InputRecord.java:505)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
        ... 16 more

    代码

    package newSpider;
    
    import java.io.IOException;
    import java.security.KeyManagementException;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLException;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.SSLSocket;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpHead;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.conn.ssl.SSLContexts;
    import org.apache.http.conn.ssl.TrustStrategy;
    import org.apache.http.conn.ssl.X509HostnameVerifier;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.util.EntityUtils;
    
    public class HttpTest {
        public static void main(String[] args) throws Exception {
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
                    SSLContext.getDefault(),
                    new String[] {"SSLv2Hello","SSLv3","TLSv1","TLSv1.1","TLSv1.2"},
                    null,
                    SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.getSocketFactory())
                    .register("https", socketFactory)
                    .build();
    
            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build();
            try (CloseableHttpResponse response = client.execute(new HttpGet("https://10.134.136.16:8888/casserver/login?service=http%3A%2F%2F10.134.136.16%3A80%2Fportal%2Findex.jsp"))) {
                System.out.println(response.getStatusLine().getStatusCode());
                System.out.println(EntityUtils.toString(response.getEntity()));
            }
        }
    }
    
    package utils;
    
    import javax.net.ssl.X509TrustManager;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    /**
     * 证书信任管理器(用于https请求)
     * 这个证书管理器的作用就是让它信任我们指定的证书,下面的代码意味着信任所有证书,不管是否权威机构颁发。
     * @author Richard_yyf
     *
     */
    public class MyX509TrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }

    问题

    经过上网之后,知道了ssl分为单向认证和双向认证,在企业应用对接时一般会采用双向认证的方式。客户端发送数据是按照服务器是单向认证时发送的,即没有将客户端证书信息一起发送给服务端。服务端验证客户端证书时,发现客户端没有证书,然后就断开了握手连接。

    1. 我所在的电脑的ie浏览器是可以访问这个目标网址的,虽然会报证书不安全的错误。既然可以访问说明客户端浏览器发送数据的时候是带着证书过去的,那我java模拟的时候是不是可以用这个证书呢?
    2. 在Stack Overflow上看到了一样的报错,我尝试过了安装JCE的方法,问题没有解决。还有就是获取一个证书然后放在java security目录,这种我还没尝试过,因为我觉得既然我浏览器可以访问,java模拟应该也可以的。还是说这不是双向认证?我理解错了?
    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • Zero子夜 普通会员 1楼
      502 Bad Gateway

      502 Bad Gateway


      nginx
    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部