JAVA https双向验证案例,和生成keyStore文件的方法,https单向认证博文参考地址

JAVA https双向验证案例,和生成keyStore文件的方法,https单向认证博文参考地址JAVA https双向验证案例,和生成keyStore文件的方法,https单向认证博文参考地址

大家好,又见面了,我是你们的朋友全栈君。

简单说下:https=http+ssl。因此在代码中就是在http的基础 上先初始化ssl证书的所有信息,二者事由很明显的界限的,在代码中都有讲解。

先解释下keyStore和trutsStore是什么:通信双方分别拥有一个keystore和一个truststore,keystore用于存放自己的密钥和公钥,truststore用于存放所有需要信任方的公钥。

下面两篇博文对https的讲解十分透彻,可参考(感谢两篇文章的博主)

Java-JSSE-SSL/TLS编程代码实例-单向认证 :

Java-JSSE-SSL/TLS编程代码实例-双向认证 

测试类:其中存在一些小编实际代码中需要自定义类,读者可忽略(重点注意红色字体部分

/**
 * 
 * @author liuxin
 * @date   2018年5月31日
 */
public class TestXiaoYing {

	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
	
		HttpConnector httpConnector = new HttpConnector();
		httpConnector.keyStorePassword="open";
		httpConnector.keyStorePath="D://xiaoying/client095.p12";
		httpConnector.trustStorePassword="kLStEz";
		httpConnector.trustStorePath="D://xiaoying/server.keystore";
		String url="https://hahah";
		//初始化加载证书等
        httpConnector.init();//1,这里是重点,也就是初始化证书,方法跳转到下面一个类的方法
        NoticeBodyRequest body=new NoticeBodyRequest();
        body.setNoticeKeyType("2");
        body.setNoticeKeyValue("20170526220000000044");
        body.setNoticeType("2");
        body.setResultCode("22");
        body.setResultDesc("ww");
        
        NoticeRequest req=new NoticeRequest();
        req.setChannelId(1);
        req.setNoticeMsg(body);
        req.setNoticeType(1);
        JsonObjectMapper jsonObjectMapper = new JsonObjectMapper();
        String request=jsonObjectMapper.writeValueAsString(req);
        System.out.println(request);
        String res=httpConnector.deal(url,"POST",request);//4,组转好入参后,调用deal方法发送请求,进入到下面一个类中
        System.out.println(res);

	}

}
public class HttpConnector {
	
	Logger logger = LoggerFactory.getLogger(getClass());
	
    public int connectTimeout = 30000;
    public int readTimeout = 10000;
    public String channel = "Test";
    public boolean isSSL = true;
    public String keyStorePath;
    public String keyStorePassword;
    public String trustStorePath;
    public String trustStorePassword;
    public String url="";

    private HttpClient httpClient;

    public void init() throws Exception {
        httpClient = new HttpClient();
        httpClient.config.connectTimeout = connectTimeout;
        httpClient.config.readTimeout = readTimeout;
        httpClient.httpConfig.userAgent = "TrustSign FEP";
        httpClient.httpConfig.contentType = MIMEType.FORM;
        httpClient.httpConfig.accept = MIMEType.JSON;
        try {
            if (isSSL) {
  
  //2,执行初始化方法,跳转到下面类的方法
                httpClient.initSSL(keyStorePath, keyStorePassword.toCharArray(), trustStorePath, trustStorePassword.toCharArray());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String deal(String uri, String method, String request) {
        HttpURLConnection connection = null;
        try {
            connection = httpClient.connect(uri, method);//5,调用connect方法,建立通讯连接
            logger.info("------请求url:"+uri);
            int responseCode = httpClient.send(connection, request == null ? null : CommonUtil.getBytes(request));
            System.out.println("responseCode:" + responseCode);
            return CommonUtil.getString(httpClient.receive(connection));
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        } finally {
            httpClient.disconnect(connection);
        }
    }
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.SecureRandom;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;



public class HttpClient{
	public static final String BOUNDARY = java.util.UUID.randomUUID().toString();
    public static final String PREFIX = "--", LINEND = "\r\n";
    public static final String DEFAULT_CHARSET = "UTF-8";

    public static final int DEFAULT_BUFFER_SIZE = 2048;
    public static final int DEFAULT_CONNECT_TIMEOUT = 3000;
    public static final int DEFAULT_READ_TIMEOUT = 30000;

    public static final String DEFAULT_SSL_PROTOCOL = "TLS";
    public static final String DEFAULT_KEY_ALGORITHM = KeyManagerFactory.getDefaultAlgorithm();
    public static final String DEFAULT_KEY_STORE_TYPE = KeyStore.getDefaultType();
    public static final String DEFAULT_TRUST_ALGORITHM = TrustManagerFactory.getDefaultAlgorithm();
    public static final String DEFAULT_TRUST_STORE_TYPE = KeyStore.getDefaultType();

    public static final String DEFAULT_HTTP_USER_AGENT = "client";
    public static final String DEFAULT_HTTP_CONNECTION = "close";
    public static final String DEFAULT_HTTP_CONTENT_TYPE = "text/plain";
    public static final String DEFAULT_HTTP_ACCEPT = "text/plain";

    class OpenSDKHostNameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            if (hostname.equals("api.hongyi.com")) {
                return true;
            }
            return false;
        }
    }

    public Config config = new Config();
    public SSLConfig sslConfig = new SSLConfig();
    public HttpConfig httpConfig = new HttpConfig();

    private SSLSocketFactory sslSocketFactory;
    //3,ssl证书初始化方法实现类,下面有重点解释
    public void initSSL(String keyStorePath, char[] keyStorePassword, String trustStorePath, char[] trustStorePassword) throws GeneralSecurityException,
            IOException {
    	/**
    	 * https客户端双向认证步骤
    	 * 
    	 * KeyStore类型有如下三种: 
			jceks - The proprietary keystore implementation provided by the SunJCE provider. 
			jks - The proprietary keystore implementation provided by the SUN provider. 
			pkcs12 - The transfer syntax for personal identity information as defined in PKCS #12.
    	 */
    	
    	//1
    	 KeyStore keyStore = KeyStore.getInstance("pkcs12"); //指定keyStore的算法类型
         InputStream inputStream = new FileInputStream(keyStorePath);
         keyStore.load(inputStream, keyStorePassword);//加载server的keyStore文件,并指定keyStore的密码keyStorePass
        
         //2
         KeyStore trustedStore = KeyStore.getInstance("JKS");//指定trustStore的算法类型
         InputStream inputStream1 = new FileInputStream(trustStorePath);
         trustedStore.load(inputStream1, trustStorePassword);//加载server的trustStore文件,并指定trustStore的密码trustStorePass


         //3
         KeyManagerFactory keyManagerFactory = null;//创建KeyManagerFactory对象
         keyManagerFactory = KeyManagerFactory.getInstance("SunX509");//指定keyManagerFactory的算法类型
         keyManagerFactory.init(keyStore, keyStorePassword);//加载1中的keyStore和server的密钥对密码keyStorePass来初始化
        
         //4
         TrustManagerFactory trustManagerFactory = null; //创建trustManagerFactory对象       
         trustManagerFactory = TrustManagerFactory.getInstance("SunX509");//指定TrustManagerFactory的算法类型
         trustManagerFactory.init(trustedStore);//加载2中的trustStore来初始化,trustStore存的是client的公钥,不需要keyPass也能访问。
         
         //5
         SSLContext sslContext = SSLContext.getInstance("TLS");//创建sslContext,并指定SSLContext的算法类型
         //加载3,4中的keymanagerFactory和trustManagerFactory对象来初始化
         sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
         sslSocketFactory = sslContext.getSocketFactory();//创建sslSocketFactory
         //至此,对ssl安全证书的双向验证的所有操作都完成了。同时,可以看出上面的所有操作都是为了得出sslSocketFactory
    }
  //6,connect实现方法,把初始化好的ssl配置加入到http中,让http变成https,至此下面的步骤可以看做http通讯的操作了
    public HttpURLConnection connect(String url, String method) throws MalformedURLException, IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        //6
        if (sslSocketFactory != null) {//承接上面的init()初始化方法,如果sslSocketFactory为null说明没有ssl证书验证,那么就可以看做http通讯了
            HttpsURLConnection httpsConn = (HttpsURLConnection) connection;//把httpURLConnection强转为HTTPsURLConnection
            httpsConn.setSSLSocketFactory(sslSocketFactory);
            if (sslConfig.ignoreHostname) {
                httpsConn.setHostnameVerifier(new OpenSDKHostNameVerifier());
            }
        }
        connection.setConnectTimeout(config.connectTimeout);
        connection.setReadTimeout(config.readTimeout);
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setRequestMethod(method);
        connection.setRequestProperty("User-Agent", "Test Example");
        connection.setRequestProperty("Connection", httpConfig.connection);
        connection.setRequestProperty("Content-Type", httpConfig.contentType + ";charset=" + config.charset);
        connection.setRequestProperty("Accept", httpConfig.accept);
        connection.setRequestProperty("Accept-Charset", config.charset);
        // NOT connect, delay until send() for set length
        return connection;
    }

    public int send(HttpURLConnection connection, byte[] requestData) throws IOException {
        if (requestData != null) {
            connection.setFixedLengthStreamingMode(requestData.length);
            connection.connect();
            OutputStream outputStream = connection.getOutputStream();
            outputStream.write(requestData);
            outputStream.flush();
        } else {
            connection.connect();
        }
        return connection.getResponseCode();
    }



    public byte[] receive(HttpURLConnection connection) throws IOException {
        InputStream inputStream = connection.getErrorStream();
        if (inputStream == null) {
            inputStream = connection.getInputStream();
        }
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(config.bufferSize);
        byte[] buffer = new byte[config.bufferSize];
        int read = -1;
        int length = 0;
        while ((read = inputStream.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, read);
            length += read;
        }
        System.out.println("length:" + length);
        return byteArrayOutputStream.toByteArray();
    }

    public void disconnect(HttpURLConnection connection) {
        connection.disconnect();
    }

    public static class Config {
        public String charset = DEFAULT_CHARSET;
        public int bufferSize = DEFAULT_BUFFER_SIZE;
        public int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
        public int readTimeout = DEFAULT_READ_TIMEOUT;
    }

    public static class SSLConfig {
        public String sslProvider = null;
        public String sslProtocol = DEFAULT_SSL_PROTOCOL;
        public String keyProvider = null;
        public String keyAlgorithm = DEFAULT_KEY_ALGORITHM;
        public String keyStoreType = DEFAULT_KEY_STORE_TYPE;
        public String trustProvider = null;
        public String trustAlgorithm = DEFAULT_TRUST_ALGORITHM;
        public String trustStoreType = DEFAULT_TRUST_STORE_TYPE;
        public boolean ignoreHostname = true;
    }

    public static class HttpConfig {
        public String userAgent = DEFAULT_HTTP_USER_AGENT;
        public String connection = DEFAULT_HTTP_CONNECTION;
        public String contentType = DEFAULT_HTTP_CONTENT_TYPE;
        public String accept = DEFAULT_HTTP_ACCEPT;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/106097.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • getParameterValues的用法「建议收藏」

    getParameterValues的用法「建议收藏」<formname="checkform"method="post"action="getvalue.jsp">你希望学习哪些程式语言:<br><inputtype="checkbox"name="langtype"value="JSP">JSP <inputtype=&q

  • Django(36)Django中间件详解「建议收藏」

    Django(36)Django中间件详解「建议收藏」什么是Django中间件中间件(Middleware)是一个用来处理Django的请求(Request)和响应(Response)的框架级别的钩子,它是一个轻量、低级别的插件系统,用于在全局范围内改

  • CSS3选择器 | 每个前端开发者必须要掌握的技术

    CSS3选择器 | 每个前端开发者必须要掌握的技术目录属性选择符伪类选择符CSS3属性CSS3自适应属性选择符如果能够灵活运用属性选择器,目前为止需要依靠id或class名才能实现的样式完全可以使用属性选择器来实现。E[att]{}:选择具有att属性的E元素E[att=”val”]{}:选择具有att属性且属性值等于val的E元素E[att~=”val”]{}:用于选取属性值中包含指定词汇的元素E[att|=”val…

  • mapGetters 辅助函数「建议收藏」

    mapGetters 辅助函数「建议收藏」1:mapGetters:辅助函数mapGetters:辅助函数mapGetters:辅助函数仅仅将store中的getter映射到局部计算属性:1:import{mapGetters}from’vuex’2:exportdefault{computer:{//使用对象展开运算符将getter混入computer对象中…mapGetters([‘getMachin…

  • 2021年美赛A题思路与程序–已更新

    2021年美赛A题思路与程序–已更新美赛第一小题部分程序%预测的菌群的数量clc;clearall;y=input(‘请输入数据’);n=length(y);yy=ones(n,1);yy(1)=y(1);fori=2:nyy(i)=yy(i-1)+y(i)endB=ones(n-1,2);fori=1:(n-1)B(i,1)=-(yy(i)+yy(i+1))/2;B(i,2)=1;endBT=B’;forj=1:(n-1)YN(j)=y(j+1);endYN=YN’;A=inv(BT

  • javascript格式化输出的实现(MuJS)

    javascript格式化输出的实现(MuJS)MuJS是一款支持嵌入式开发的轻量级javascript解释器。javascript主要是针对web开发的脚本语言,所以主要借助浏览器来调试;但mujs针对的是嵌入式开发,调试时的交互主要靠输入输出终端,javascript本身是不支持的,所以需要调用c语言的打印函数来实现。下面给出两个例子,一个是普通输出,符合脚本语言的解释性语言的特点,不考虑变量的类型;另一个是简单的格式化输出。前一个…

    2022年10月31日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号