java + https + tomcat 双向认证(含证书生成和代码实现)

 JAVA 代码

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;

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

import net.sf.json.JSONObject;


/**
 * 

* Description *

* * @author Admin * @date 2019年4月23日 */ public class HttpsPost { /** * 加载私钥证书 * * @param keyStore * @param keyStorePass * @return * @throws IOException */ private static KeyManager[] getKeyManagers(String keyStore, String keyStorePass) throws Exception { try { // 获取默认的 X509算法 String alg = KeyManagerFactory.getDefaultAlgorithm(); // 创建密钥管理工厂 KeyManagerFactory factory = KeyManagerFactory.getInstance(alg); InputStream fp = new FileInputStream(keyStore); KeyStore ks = KeyStore.getInstance("JKS");//PKCS12 ks.load(fp, keyStorePass.toCharArray()); fp.close(); factory.init(ks, keyStorePass.toCharArray()); KeyManager[] keyms = factory.getKeyManagers(); //System.out.println(keyms); return keyms; }catch (Exception e) { e.printStackTrace(); } return null; } /** * 加载信任证书库 * * @param trustStore * @param trustStorePass * @return * @throws IOException */ private static TrustManager[] getTrustManagers(String trustStore, String trustStorePass) throws Exception { try { // 信任仓库的默认算法X509 String alg = TrustManagerFactory.getDefaultAlgorithm(); // 获取信任仓库工厂 TrustManagerFactory factory = TrustManagerFactory.getInstance(alg); // 读取信任仓库 InputStream fp = new FileInputStream(trustStore); // 密钥类型 KeyStore ks = KeyStore.getInstance("JKS"); // 加载密钥 ks.load(fp, trustStorePass.toCharArray()); fp.close(); factory.init(ks); TrustManager[] tms = factory.getTrustManagers(); //System.out.println(tms); return tms; } catch (Exception e) { e.printStackTrace(); } return null; } // 直接通过主机认证 private final static HostnameVerifier VERIFY = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; public static String https(String url, Map params){ // 构建请求参数 String result = ""; PrintWriter out = null; BufferedReader in = null; HttpsURLConnection urlCon = null; JSONObject json = JSONObject.fromObject(params); String sendString = json.toString(); System.out.println("=====https发送的数据为:\t" + sendString); try { // 授信证书库 String trustStore = "D:\\workSoft\\cer\\trustOfClient.keystore"; String trustStorePass = "123456"; // 私钥证书 String keyStore = "D:\\workSoft\\cer\\client.keystore"; String keyStorePass = "123456"; TrustManager[] tms = getTrustManagers(trustStore, trustStorePass); KeyManager[] kms = getKeyManagers(keyStore, keyStorePass); SSLContext sslContext = SSLContext.getInstance("SSL");//"SunJSSE" //SSLContext sslContext = SSLContext.getInstance("TLS");//TLS SSL // 如果服务器不要求私钥证书,kms 可以不填 sslContext.init(kms, tms,null );//new java.security.SecureRandom() SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url2 = new URL(url); urlCon = (HttpsURLConnection) url2.openConnection(); urlCon.setSSLSocketFactory(ssf); urlCon.setHostnameVerifier(VERIFY); urlCon.setDoOutput(true); urlCon.setDoInput(true); urlCon.setRequestMethod("POST"); urlCon.setRequestProperty("Content-type", "application/json;charset=UTF-8"); urlCon.setRequestProperty("accept", "*/*"); //请求报文可通过一个“Accept”报文头属性告诉服务端 客户端接受什么类型的响应 urlCon.setRequestProperty("connection", "Keep-Alive");//表示是否需要持久连接。(HTTP 1.1默认进行持久连接)Keep-Alive为持久连接 //urlCon.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 7.0; WOW64)"); urlCon.setConnectTimeout(3*1000);//设置超时时间 urlCon.setReadTimeout(3*1000); // 发送POST请求必须设置如下两行 urlCon.setDoOutput(true); urlCon.setDoInput(true); // 获取URLConnection对象对应的输出流 OutputStream os = urlCon.getOutputStream(); //参数是键值队 , 不以"?"开始 os.write(sendString.getBytes()); os.flush(); // 发送请求参数 // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(urlCon.getInputStream(),"GBK")); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { e.printStackTrace(); //https(url,params); return null; } finally {// 使用finally块来关闭输出流、输入流 try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } urlCon.disconnect(); } System.out.println("=====https接受的数据为:\t" + result); return result; } public static void main(String[] args) throws Exception { Map map= new HashMap(); map.put("laneNo", "35"); map.put("laneType", "02"); map.put("provinceCode", "1101"); map.put("psamNo", "11010000000000000001"); map.put("roadCode", "1"); map.put("roadName", "xx高速"); map.put("stationCode", "2"); map.put("stationName", "xx收费站"); map.put("stationType", "02"); map.put("terminalNo", "110100000000"); map.put("terminalTime", "2018-07-04 12:12:12"); String url="https://127.0.0.1:4566/obuReplaceSecretKey/obu/test"; System.out.println(https(url, map)); } }

证书生成

1 生成服务器证书库

keytool -genkey -keyalg RSA -keysize 2048 -validity 365000 -alias server -keypass 123456 -keystore server.keystore -storepass  123456 -dname "CN= 106.39.79.26:4144,OU=JL,O=JL,L=BJ,ST=BJ,C=CN"

 其中,-keyalg 指定算法,

   -keysize指定密钥大小,

   -validity指定有效期,单位为天,

   -alias  别名

   -keypass 指定私钥使用密码,

   -keystore指定密钥库名称,

   -storepass 证书库的使用密码,从里面提取公钥时需要密码

   -dname :CN拥有者名字,一般为网站名或IP+端口,如www.baidu.com,OU组织机构名 O组织名 L城市 ST州或省 C国家代码

2. 导出公钥:

    keytool -export -alias server -file server.crt -keystore server.keystore -storepass  123456

3. 将服务端证书,加入客户端的认证证书列表中       

   keytool -import -alias server -file server.crt -keystore trustOfClient.keystore -storepass  123456

4. 生成client端密钥

    keytool -genkey -keyalg RSA -keysize 2048 -validity 365000 -alias client -keypass 123456 -keystore client.keystore -storepass 123456 -dname "CN=localhost,OU=JL,O=JL,L=BJ,ST=BJ,C=CN"

5. 导出公钥:

    keytool -export -alias client -file client.crt -keystore client.keystore -storepass 123456

6. 将证书加到服务端信任列表

   keytool -import -alias server -file client.crt -keystore trustOfServer.keystore -storepass 123456

配置tomcat

修改server.xml配置文件,在server.xml配置文件加入如下信息

           maxThreads="150" scheme="https" secure="true"
           clientAuth="true" sslProtocol="SSL"
           keystoreFile="D:\\workSoft\\cer\\server.keystore" 
           keystorePass="123456"
           truststoreFile="D:\\workSoft\\cer\\trustOfServer.keystore" 
           truststorePass="123456"
           />

你可能感兴趣的:(java + https + tomcat 双向认证(含证书生成和代码实现))