如何使用HttpClient来发送带客户端证书的请求,以及如何忽略掉对服务器端证书的校验

最近要做客户端和服务器端的双向认证,在客户端向服务器端发送带证书的请求这里有一点问题,网上的例子大多都不太好使,于是找了github上httpclient源代码中的例子改造了一下,终于弄明白了

github上我参考的例子在:https://github.com/apache/httpclient/blob/4.5.x/httpclient/src/examples/org/apache/http/examples/client/ClientCustomSSL.java

下面先贴上我自己的代码(需要导入HttpClient等相关jar包),然后再说明

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/*
 * Created with Intellij IDEA
 * USER: 焦一平
 * Date: 2016/5/8
 * Time: 1:10
 * To change this template use File | Settings | File Template
 */
public class SSLDemo {
    public static void main(String[] args) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\client.pfx")), "123456".toCharArray());
        SSLContext sslcontext = SSLContexts.custom()
                //忽略掉对服务器端证书的校验
                .loadTrustMaterial(new TrustStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        return chain.length == 1;
                    }
                })
                .loadKeyMaterial(keyStore, "123456".toCharArray())
                .build();
        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
                sslcontext,
                new String[]{"TLSv1"},
                null,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslConnectionSocketFactory)
                .build();

        try {

            HttpGet httpget = new HttpGet("https://192.168.62.130/status.jsp");

            System.out.println("Executing request " + httpget.getRequestLine());

            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                HttpEntity entity = response.getEntity();
                System.out.println(response.getStatusLine());
                System.out.println(IOUtils.toString(entity.getContent()));
                EntityUtils.consume(entity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}
SSLContexts.custom() 方法返回一个 SSLContextBuilder实例,来构建SSLContext,下面是SSLContextBuilder的方法列表:

其中:       loadKeyMaterial()重载方法是加载客户端证书用的       loadTrustMaterial()重载方法是加载服务器端相关信息用的(我们就是使用 loadTrustMaterial(TrustStrategy trustStrategy) 方法自己实现了一个信任策略,不对服务器端的证书进行校验),

在生成HttpClient的时候,指定相应的 SSLSocketFactory,之后,使用这个HttpClient发送的GET请求和POST请求就自动地附加上了证书信息

如果我们只需要忽略掉对服务器端证书的验证,而不需要发送客户端证书信息,在构建SSLContext的时候,只需要 loadTrustMaterial() 不需要 loadKeyMaterial()

客户端如何只信任某个服务器端的证书信息 会在之后的文章中写
时间: 2024-12-19 09:11:58

如何使用HttpClient来发送带客户端证书的请求,以及如何忽略掉对服务器端证书的校验的相关文章

Postman发送带cookie的http请求

Postman是chrome上一个非常好用的http客户端插件,可惜由于chrome安全的限制,发不出带cookie的请求.如果想要发送带cookie的请求,需要开启Interceptor: 这个Interceptor还需要到chrome应用商店下载 Postman Interceptor 扩展程序.现在能发送带cookie的http请求.发送cookie时,在header中添加key-value,key固定为Cookie,value是cookie具体的k=v,例如: 需要注意的是,发送带coo

发送带参数的get请求,并解决httpclient编码问题

package cn.wemart.httppost; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList;

HttpClient 的GET(带参数)、POST请求方式,工具类方法

/** * 连接/断开操作 post方式 * @param url * @param json */ private boolean connOrDisconnOperator(String url,String json){ CloseableHttpClient client = null; CloseableHttpResponse response = null; boolean flag = false; try{ HttpPost httpPost = new HttpPost(ur

java 发送带cookie的http请求

try{     String path = "https://www.AA.com/AA";         URL url = new URL(path);         HttpURLConnection con = (HttpURLConnection) url.openConnection();         con.setRequestMethod("GET");         /*con.setRequestProperty("Cont

python+requests——发送带参数的get请求

Requests 允许你使用 params 关键字参数,以一个字符串字典来提供这些参数. 举例来说,如果你想传递 key1=value1 和 key2=value2 到 httpbin.org/get ,那么你可以使用如下代码: payload = {'key1': 'value1', 'key2': 'value2'} resp = requests.get("http://httpbin.org/get", params=payload,timeout=0.5) 原文地址:http

Android上发送带附件的邮件

准备工作-下载最新版本的JMail https://java.net/projects/javamail/pages/Home#Download_JavaMail_1.5.2_Release http://www.oracle.com/technetwork/java/javase/downloads/index-135046.html 在android上发送邮件方式: 第一种:借助GMail APP客户端,缺点是必须使用GMail帐号,有点是比较方便 不需要写很多代码,但是不是很灵活. 第二种

使用Spring发送带附件的电子邮件(站内和站外传送)

JavaMail的介绍 JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口.它是Sun发布的用来处理email的API.它可以方便地执行一些常用的邮件传输.   虽然JavaMail是Sun的API之一,但它目前还没有被加在标准的java开发工具包中(Java Development Kit),这就意味着你在使用前必须另外下载JavaMail文件.除此以外,你还需要有Sun的JavaBeans Activation Framework (JAF).JavaBeans Activa

微信支付 带apiclient_cert.p12证书的请求方法 JAVA版

以下是带apiclient_cert.p12证书的请求方法 package utils.wechat; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.KeyStore; import javax.net.ssl.SSLContext; import org.apache.http.HttpEntity; import org.apache.

zabbix 发送带图片的报警信息到微信

过程比较复杂 先用curl到报警对于itemid的图片 将图片上传到微信企业号 去的微信的mediaid 在发送给客户端.代码还在整理中