httpclient调用Https,加载自签名证书

来源:互联网 发布:工程预算软件免费下载 编辑:程序博客网 时间:2024/05/19 19:32

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.security.KeyManagementException;

import java.security.KeyStore;

import java.security.NoSuchAlgorithmException;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;


import javax.net.ssl.SSLContext;

import javax.net.ssl.TrustManager;

import javax.net.ssl.TrustManagerFactory;


import org.apache.http.HttpEntity;

import org.apache.http.NameValuePair;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.entity.UrlEncodedFormEntity;

import org.apache.http.client.methods.CloseableHttpResponse;

import org.apache.http.client.methods.HttpPost;

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.PlainConnectionSocketFactory;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;

import org.apache.http.conn.ssl.SSLContexts;

import org.apache.http.conn.ssl.TrustSelfSignedStrategy;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import org.apache.http.message.BasicNameValuePair;

import org.apache.http.util.EntityUtils;


import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException;


public class HttpsClient2 {

    /**

     * 设置信任自签名证书

     * 

     * @param keyStorePath 密钥库路径

     * @param keyStorepass 密钥库密码

     * @return

     */

    public static SSLContext custom(StringkeyStorePath, String keyStorepass) {

        SSLContext sc = null;

        FileInputStream instream = null;

        KeyStore trustStore = null;

        try {

            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());

            

            instream = new FileInputStream(new File(keyStorePath));

            trustStore.load(instream,keyStorepass.toCharArray());

            // 相信自己的CA和所有自签名的证书

            sc = SSLContexts.custom().loadTrustMaterial(trustStore,new TrustSelfSignedStrategy()).build();

            // 构造 javax.net.ssl.TrustManager 对象

            TrustManagerFactory tmf =

            TrustManagerFactory.getInstance("SunX509","SunJSSE");

            tmf.init(trustStore);

            TrustManager tms [] = tmf.getTrustManagers();

            // 使用构造好的 TrustManager 访问相应的 https 站点

            SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE");

            sslContext.init(null,tms, new java.security.SecureRandom());

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            try {

                instream.close();

            } catch (IOException e) {

            }

        }

        return sc;

    }


    /**

     * 模拟请求

     * 

     * @param url 资源地址

     * @param map 参数列表

     * @param encoding 编码

     * @return

     * @throws ParseException

     * @throws IOException

     * @throws KeyManagementException

     * @throws NoSuchAlgorithmException

     * @throws ClientProtocolException

     */

    public static String post(Stringurl, Map<String, String> map)

            throws ClientProtocolException, IOException {

        String body = "";

 

       try

        SSLContext sslcontext = HttpsClient2.custom("/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/security/cacerts","changeit");

        // 设置协议httphttps对应的处理socket链接工厂的对象

        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()

                .register("http", PlainConnectionSocketFactory.INSTANCE)

                .register("https", new SSLConnectionSocketFactory(sslcontext)).build();

        PoolingHttpClientConnectionManager connManager =new PoolingHttpClientConnectionManager(socketFactoryRegistry);

        // 创建自定义的httpclient对象

        CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();

        // 创建post方式请求对象

        HttpPost httpPost = new HttpPost(url);


        // 装填参数

        List<NameValuePair> nvps = new ArrayList<NameValuePair>();

        if (map != null) {

            for (Entry<String, String> entry : map.entrySet()) {

                nvps.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));

            }

        }

        // 设置参数到请求对象中

        httpPost.setEntity(new UrlEncodedFormEntity(nvps,"UTF-8"));

        System.out.println("请求地址:"+url);  

        System.out.println("请求参数:"+nvps.toString());  

          

        //设置header信息  

        //指定报文头【Content-type】、【User-Agent】  

        httpPost.setHeader("Content-type","application/x-www-form-urlencoded");  

        httpPost.setHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");


        // 执行请求操作,并拿到结果(同步阻塞)

        CloseableHttpResponse response = client.execute(httpPost);

        // 获取结果实体

        HttpEntity entity = response.getEntity();

        if (entity !=null) {

            // 按指定编码转换结果实体为String类型

            body = EntityUtils.toString(entity,"UTF-8");

           

        }

        EntityUtils.consume(entity);

        // 释放链接

        response.close();

       }catch(Exception e){

           System.out.println(e);

       }

        return body;

    }

    public static void main(String[] args){

      String body;

    try {

        body = post("https://payment.qa.17usoft.net/fi-web/quick/payment",null);

        System.out.println(body);

    } catch (ClientProtocolException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    } catch (IOException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    }

   

        

    }


导入证书:

sudo keytool -import -alias mystore  -file /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/security/TongChengCACRT.crt -keystore /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/security/cacerts

遇到的问题:

(1)hostname in certificate didn't match:  验证https域名与证书域名不匹配,查找各种问题,最终定位的httpclient包版本的问题,4.3.1版本号换成4.3.6版本号解决

(2)pkix path building failed:   客户端JDK版本要与服务器JDK版本一致解决

  

参考:

Java 使用自签证书访问https站点:

http://blog.chenxiaosheng.com/posts/2013-12-26/java-use-self_signed_certificate.html

Java 和 HTTP 的那些事(四) HTTPS 和 证书 :

 http://www.aneasystone.com/archives/2016/04/java-and-https.html    

HTTPS证书生成原理和部署细节:

http://www.barretlee.com/blog/2015/10/05/how-to-build-a-https-server/


0 0
原创粉丝点击