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
修改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"
/>