一、服务端
1. 生成密钥库 --- kserver.keystore 是给服务端用的,其中保存着自己的私钥
keytool -genkey -alias serverkey -keystore ./kserver.keystore -dname CN=test-server,OU=CTF,O=CTF1,L=SHH,ST=SHH,C=CN -validity 36500 -keysize 1024 -keyalg RSA -storepass 123456 -v
2. 导出密钥证书kserver.cer --- 根据私钥,导出服务端证书
keytool -export -alias serverkey -keystore ./kserver.keystore -file ./kserver.cer -storepass 123456
3. 生成服务端信任密钥库 (可以与密钥库使用同一个)
keytool -genkey -alias servertrustkey -keystore ./kservertrust.keystore -dname CN=test-server-trust,OU=CTF,O=CTF1,L=SHH,ST=SHH,C=CN -validity 36500 -keysize 1024 -keyalg RSA -storepass 123456trust -v
4. 将证书导入客户端信任库(客户端信任库在后续创建)
keytool -import -alias serverkey -file kserver.cer -keystore kclienttrust.keystore
5. 查看证书内容
keytool -list -v -keystore kserver.keystore -storepass 123456
keytool -list -v -keystore kservertrust.keystore -storepass 123456trust
二、客户端
1. 生成密钥库 --- kclient.keystore 是给服务端用的,其中保存着自己的私钥
keytool -genkey -alias clientkey -keystore ./kclient.keystore -dname CN=test-client,OU=CTF,O=CTF1,L=SHH,ST=SHH,C=CN -validity 36500 -keysize 1024 -keyalg RSA -storepass 123456 -v
2. 导出密钥证书 kclient.cer --- 根据私钥,导出服务端证书
keytool -export -alias clientkey -keystore ./kclient.keystore -file ./kclient.cer -storepass 123456
3. 生成客户端信任密钥库
keytool -genkey -alias clienttrustkey -keystore ./kclienttrust.keystore -dname CN=test-client-trust,OU=CTF,O=CTF1,L=SHH,ST=SHH,C=CN -validity 36500 -keysize 1024 -keyalg RSA -storepass 123456trust -v
此时得到如下6个文件:
4. 将证书导入服务端信任库
keytool -import -alias clientkey -file kclient.cer -keystore kservertrust.keystore
5. 查看证书内容
keytool -list -v -keystore kclient.keystore -storepass 123456
keytool -list -v -keystore kclienttrust.keystore -storepass 123456trust
注:后续代码中会用到:
服务端(tomcat/weblogic):kserver.keystore、kservertrust.keystore
客户端(程序):kclient.keystore、kclienttrust.keystore
三、服务器配置
1. Tomcat 服务器配置
Tomcat安装目录/conf/server.xml 中添加,其中clientAuth=true代表开启双向验证
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="/home/https/kserver.keystore" keystorePass="123456"
truststoreFile="/home/https/kserver.keystore" truststorePass="123456"/>
2. Weblogic服务器配置
最后激活重新部署。
四、自签名证书
自签名证书:对于每一个要链接的服务器,都要保存一个证书的验证副本,而且一旦服务器更换证书,所有客户端就需要重新部署这些副本。要解决这一问题可以使用openssl,或者使用第三方信任机构颁发的证书。
五、HttpsUtil工具类 - 客户端
/**
* 使用httpclient4.x.x实现https双向验证
*/
public class Https4client {
public static void main(String[] args) throws Exception {
HttpClient httpclient = getHttpClient();
HttpEntity entity=null;
//1.get测试
// HttpGet get = new HttpGet("https://自己服务器IP:端口/test/doget");
// HttpResponse rsp = httpclient.execute(get);
//2.post测试
HttpPost post = new HttpPost("https://自己服务器IP:端口/test/dopost");
StringEntity stringEntity = new StringEntity("test post method!", Charset.forName("UTF-8"));
post.setEntity(stringEntity);
HttpResponse rsp = httpclient.execute(post);
entity = rsp.getEntity();
//用EntityUtils.toString()这个静态方法将HttpEntity转换成字符串,防止服务器返回的数据带有中文,所以在转换的时候将字符集指定成utf-8就可以了
String result= EntityUtils.toString(entity, "UTF-8");
System.out.println("-------------------------result:"+result+"-------------");
if(rsp.getStatusLine().getStatusCode()==200){
System.out.println(rsp.getStatusLine().getStatusCode()+"-----------success------------------");
}else{
System.out.println(rsp.getStatusLine().getStatusCode()+"------------------fail-----------");
}
}
public static HttpClient getHttpClient() throws Exception{
//设置http参数
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "UTF-8");
HttpProtocolParams.setUseExpectContinue(params, true);
HttpConnectionParams.setConnectionTimeout(params, 5000);//连接超时
HttpConnectionParams.setSoTimeout(params, 5000);//请求超时
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
SSLSocketFactory sf = getBidirectionalSSL();
schReg.register(new Scheme("https", 443, sf));
PoolingClientConnectionManager pccm = new PoolingClientConnectionManager(
schReg);
pccm.setMaxTotal(100); // 客户端总并行链接最大数
pccm.setDefaultMaxPerRoute(20); // 发送到指定主机的最大连接数
DefaultHttpClient httpclient = new DefaultHttpClient(pccm, params);
// //设置代理 DNS
// HttpHost proxy = new HttpHost("10.112.24.30", 8019);
// httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
return httpclient;
}
/**
* 双向ssl 设置客户端证书
* @return
*/
public static SSLSocketFactory getBidirectionalSSL() throws Exception {
//客户端证书库,上面生成的kclient.keystore
File certFile = new File(GetConfigUtil.getProjectConfig("ssl.client.keystore"));
KeyStore ks = null;
try {
ks = KeyStore.getInstance("JKS");
} catch (KeyStoreException e) {
throw new Exception(e);
}
//密钥库密码 123456
String password = "";
try {
password = GetConfigUtil.getProjectConfig("client.store.file.password");
ks.load(new FileInputStream(certFile), password.toCharArray());
} catch (NoSuchAlgorithmException e) {
throw new Exception(e);
} catch (CertificateException e) {
throw new Exception(e);
} catch (FileNotFoundException e) {
throw new Exception(e);
} catch (IOException e) {
throw new Exception(e);
}
KeyManagerFactory kmf = null;
try {
kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
} catch (NoSuchAlgorithmException e) {
throw new Exception(e);
}
try {
kmf.init(ks, password.toCharArray());
} catch (UnrecoverableKeyException e) {
throw new Exception(e);
} catch (KeyStoreException e) {
throw new Exception(e);
} catch (NoSuchAlgorithmException e) {
throw new Exception(e);
}
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException e) {
throw new Exception(e);
}
try {
sslContext.init(kmf.getKeyManagers(), getTrustManager(), null);
} catch (KeyManagementException e) {
throw new Exception(e);
} catch (Exception e) {
throw new Exception(e);
}
SSLSocketFactory factory = new SSLSocketFactory(sslContext,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return factory;
}
/**
* 双向SSL 认证服务器的证书
* @return
* @throws Exception
*/
public static TrustManager[] getTrustManager() throws Exception{
TrustManager[] trustManager=null;
String password = "";
//上面生成的kclienttrust.keystore
String publicKey = GetConfigUtil.getProjectConfig("ssl.clienttrust.keystore");
if(null ==publicKey ||"".equals(publicKey)){
throw new RuntimeException("信任库证书未配置");
}else{
//第三方机构服务器的公钥证书
File publicFile = new File(publicKey);
KeyStore pks = KeyStore.getInstance("JKS");
password = GetConfigUtil.getProjectConfig("client.trust.file.password");
pks.load(new FileInputStream(publicFile), password.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
tmf.init(pks);
trustManager = tmf.getTrustManagers();
}
return trustManager;
}
}
GetConfigUtil我就不贴了吧,还是要自己动动脑子的,不能彻底无脑CV流~~
算了我还是分享出来吧
项目地址:https://gitee.com/defense-of-the-anciant2/market-purchase