httpclient3.1跳过ssl验证

原来的老项目调用一个Http的服务,最近http的服务调整成了https,因此需要调整一下,网上大部分都是4.5以上版本,3.1版本处理方法比较少,因此记录一下

一、实现两个类

1.MyX509TrustManager

复制代码
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
 
public class MyX509TrustManager implements X509TrustManager {
    /* (non-Javadoc)
    * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String)
    */
    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
 
    }
    /* (non-Javadoc)
     * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String)
     */
    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
 
    }
    /* (non-Javadoc)
     * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
     */
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

2.MySecureProtocolSocketFactory

项目使用的jdk版本是1.8,jdk版本默认协议需要指定一下,因此SSLContext context = SSLContext.getInstance("TLSv1.2");

复制代码
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
 
public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {
 
    //添加一个属性,主要目的获取ssl跳过验证
    private SSLContext sslContext = null;
    /**
     * Constructor for MySecureProtocolSocketFactory.
     */
    public MySecureProtocolSocketFactory() {
    }
    /**
     * 创建一个获取SSLContext的方法,导入MyX509TrustManager进行初始化
     * @return
     */
    private static SSLContext createEasySSLContext() {
        try {
            SSLContext context = SSLContext.getInstance("TLSv1.2");
            context.init(null, new TrustManager[] { new MyX509TrustManager() },
                    null);
            return context;
        } catch (Exception e) {
            throw new HttpClientError(e.toString());
        }
    }
 
    /**
     * 判断获取SSLContext
     * @return
     */
    private SSLContext getSSLContext() {
        if (this.sslContext == null) {
            this.sslContext = createEasySSLContext();
        }
        return this.sslContext;
    }
    //后面的方法基本上带入相关参数
    /*
     * (non-Javadoc)
     *
     * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String,
     *      int, java.net.InetAddress, int)
     */
    public Socket createSocket(String host, int port, InetAddress clientHost,int clientPort) throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(host, port,clientHost, clientPort);
    }
 
    /*
     * (non-Javadoc)
     *
     * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String,
     *      int, java.net.InetAddress, int,
     *      org.apache.commons.httpclient.params.HttpConnectionParams)
     */
    public Socket createSocket(final String host, final int port,final InetAddress localAddress, final int localPort,
                               final HttpConnectionParams params) throws IOException,UnknownHostException, ConnectTimeoutException {
        if (params == null) {
            throw new IllegalArgumentException("Parameters may not be null");
        }
        int timeout = params.getConnectionTimeout();
        if (timeout == 0) {
            return createSocket(host, port, localAddress, localPort);
        } else {
            return ControllerThreadSocketFactory.createSocket(this, host, port,localAddress, localPort, timeout);
        }
    }
 
    /*
     * (non-Javadoc)
     *
     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
     */
    public Socket createSocket(String host, int port) throws IOException,UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(host, port);
    }
 
    /*
     * (non-Javadoc)
     *
     * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
     */
    public Socket createSocket(Socket socket, String host, int port,boolean autoClose) throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(socket, host,port, autoClose);
    }
}

最后声明MySecureProtocolSocketFactory加入Protocol就可以了。

复制代码
        //声明
        ProtocolSocketFactory fcty = new MySecureProtocolSocketFactory();
        //加入相关的https请求方式
        Protocol.registerProtocol("https", new Protocol("https", fcty, 443));
        //发送请求
        org.apache.commons.httpclient.HttpClient httpclient = new org.apache.commons.httpclient.HttpClient();
        GetMethod httpget = new GetMethod(url);
        System.out.println("======https的服务地址url:" + url);
        try {
            httpclient.executeMethod(httpget);
            return httpget.getResponseBodyAsString();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new Exception(ex.getMessage());
        } finally {
            httpget.releaseConnection();
        }

实现完后自信满满重新打包更新上正式环境,结果报错了。。。

java 复制代码
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Certificates do not conform to algorithm constraints


	at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)


	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)


	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)


	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)


	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)


	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)


	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)


	at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)


	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)


	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)

百度一下这个问题,证书不符合算法约束,基本都是修改配置文件$JAVA_HOME/jre/lib/security/java.security,但是项目是docker部署的,jdk用的是docker里面的,外面服务器里的jdk版本都是11,那每次更新服务都得手动改配置也太麻烦了吧。。。

===================================================================

后面找到一篇文章,修改前面的实现类,把自己实现的类改写成继承新的抽象类:X509ExtendedTrustManager即可,代码如下:

java 复制代码
//public class MyX509TrustManager implements X509TrustManager {
public class MyX509TrustManager extends X509ExtendedTrustManager {
//实现方法,所有方法都是空方法
}

再次更新代码,问题解决!

参考:httpclient 3.1跳过https请求SSL的验证_鼓逗猫柠的博客-CSDN博客
https://www.cnblogs.com/flyingeagle/articles/7508207.html

相关推荐
辣椒思密达8 小时前
AI出海产品本地化测试:住宅IP在模拟海外用户环境中的实践价值
网络协议·tcp/ip·安全·php·苹果vision pro
花生了什么事o10 小时前
DNS:把域名翻译成 IP 的层级查询机制
网络·网络协议·tcp/ip
2401_8734794012 小时前
金融合规新规下IP查询怎么做?用IP离线库实现数据不出域
网络协议·tcp/ip·金融·ip
微硬创新14 小时前
汽车制造产线协同:耐达讯PROFINETDeviceNet网关在机器人通信中的应用
人工智能·物联网·网络协议·自动化·汽车·制造·信息与通信
米尔的可达鸭14 小时前
深入操作系统 Socket 底层:套接字控制块、FD映射、阻塞IO核心完整实现
arm开发·数据结构·websocket·网络协议·算法·架构·安全架构
Keepingrun15 小时前
http登录和授权
网络·网络协议·http
Lhappy嘻嘻17 小时前
网络初识|基础入门:局域网广域网、IP 端口、TCP/IP 五层模型与封装解封装全过程
java·开发语言·网络·笔记·网络协议·tcp/ip
laoli_coding1 天前
如何配置HTTPS站点访问的免费SSL域名证书
网络协议·https·node.js·ssl
Keepingrun1 天前
HTTP基础
网络·网络协议·http
apihz2 天前
全球域名 WHOIS 信息实时查询免费 API 接口教程,支持1000+后缀
android·网络·网络协议·tcp/ip·apache·域名·whois