java https tomcat 单双认证(含证书生成和代码实现) 原创转载请备注,谢谢O(∩_∩)O
server: apache-tomcat-6.0.44 jdk1.7.0_79
client: jdk1.7.0_79
jks是JAVA的keytools证书工具支持的证书私钥格式。 pfx是微软支持的私钥格式。 cer是证书的公钥。
生成:
keytool -genkey -alias tbb -keyalg RSA -keystore D:\cert\tbb.keystore
模板:
keytool -genkey -alias yushan -keypass yushan -keyalg RSA -keysize 1024 -validity 365((默认为90天)) -keystore D:\cert\tbb.keystore -storepass 123456 -dname "CN=(名字与姓氏), OU=(组织单位名称), O=(组织名称), L=(城市或区域名称), ST=(州或省份名称), C=(单位的两字母国家代码)";(中英文即可)
验证:
keytool -selfcert -alias tbb -keystore D:\cert\tbb.keystore
导出:
keytool -export -alias tbb -keystore D:\cert\tbb.keystore -storepass 12345678 -rfc -file D:\cert\tbb.cer
转换 cer -> jks
keytool -import -alias mycert -file D:\cert\tbb.cer -keystore D:\cert\tbb.jks keystore信息的查看:
打印证书的 MD5 指纹
keytool -list -v -keystore D:\cert\tbb.keystore -storepass 12345678
可打印的编码格式输出证书
keytool -list -rfc -keystore D:\cert\tbb.keystore -storepass 12345678
生成客户端证书库
keytool -validity 36500 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore D:\cert\client.p12 -dname "CN=spring,OU=jiajianfa,O=jiajianfa,L=Wuhan,ST=HuBei,c=cn" -storepass 12345678 -keypass 12345678
从客户端证书库中导出客户端证书
keytool -export -v -alias client -keystore D:\cert\client.p12 -storetype PKCS12 -storepass 12345678 -rfc -file D:\cert\client.cer 将客户端证书导入到服务器证书库(使得服务器信任客户端证书,服务器端用此验证客户端的合法性)
keytool -import -v -alias client -file D:\cert\client.cer -keystore D:\cert\tbb.keystore -storepass 12345678 查看服务端证书中信任的客户端证书
keytool -list -keystore D:\cert\tbb.keystore -storepass 12345678
tomcat server.xml 配置:
<!-- clientAuth true:双向认证 false:单向认证-->
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS" keystorePass="12345678" keystoreFile="D:\cert\tbb.keystore"
truststoreFile="D:\cert\tbb.keystore" truststorePass="12345678" />
<!-- 配置服务端项目web.xml 在<welcome-file-list>之后增加:--> <!-- 强制SSL配置,即普通的请求也会重定向为SSL请求 -->
<security-constraint>
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<url-pattern>/*</url-pattern><!-- 全站使用SSL <url-pattern>/*</url-pattern>-->
</web-resource-collection>
<user-data-constraint>
<description>SSL required</description>
<!-- CONFIDENTIAL: 要保证服务器和客户端之间传输的数据不能够被修改,且不能被第三方查看到 -->
<!-- INTEGRAL: 要保证服务器和client之间传输的数据不能够被修改 -->
<!-- NONE: 指示容器必须能够在任一的连接上提供数据。(即用HTTP或HTTPS,由客户端来决定)-->
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
单向认证:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
import java.util.Date; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession; /**
* @Description https单向认证
* @author sprinng
*
*/
public class ClientSendDataSingle {
/**
*
* @param sendurl 请求地址
* @param res 返回结果
* @param sendData 参数
* @param timeOut 超时时间(min)
* @param useProxy 是否使用代理
* @param trustStorePath 证书路径
* @param trustStorePwd 证书密码
* @return
* @throws Exception
*/
public static String send(String sendurl, String res, String sendData, String timeOut, boolean useProxy, String trustStorePath, String trustStorePwd)throws Exception {
System.setProperty("javax.net.ssl.trustStore", trustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePwd);
URL url = new URL(sendurl);
HttpsURLConnection connection = null;
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
System.setProperty("java.protocol.handler.pkgs","sun.net.www.protocol");
HttpsURLConnection.setDefaultHostnameVerifier(hv);
Date current = new Date(System.currentTimeMillis());
System.out.println("begint to open connection at " + current);
//使用代理
if(useProxy){
InetSocketAddress isa = new InetSocketAddress(PropertiesUtil.properties.getProperty("proxy_host"), Integer.parseInt(PropertiesUtil.properties.getProperty("proxy_port")));
Proxy proxy = new Proxy(Proxy.Type.HTTP, isa);
Authenticator.setDefault(new MyAuthenticator(PropertiesUtil.properties.getProperty("proxy_user"), PropertiesUtil.properties.getProperty("proxy_password")));
connection = (HttpsURLConnection) url.openConnection(proxy);
}else{
connection = (HttpsURLConnection) url.openConnection();
}
Date end = new Date(System.currentTimeMillis());
System.out.println("open connection ok at " + end + ",cost:"+ (end.getTime() - current.getTime()));
connection.setRequestProperty("Content-Type", "text/xml");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setReadTimeout(60 * 1000 * Integer.parseInt(timeOut));
byte data[] = sendData.getBytes();
current = new Date(System.currentTimeMillis());
System.out.println("[SSLIX]notifyEai,begint to write data at " + current);
OutputStream out = connection.getOutputStream();
out.write(data);
end = new Date(System.currentTimeMillis());
System.out.println("write data ok at " + end + ",cost:" + (end.getTime() - current.getTime()));
StringBuffer receivedData = new StringBuffer();
current = new Date(System.currentTimeMillis());
System.out.println("begint to read data at " + current);
InputStreamReader inReader = new InputStreamReader(connection.getInputStream(), "UTF-8");
BufferedReader aReader = new BufferedReader(inReader);
String aLine;
while ((aLine = aReader.readLine()) != null) {
receivedData.append(aLine);
}
end = new Date(System.currentTimeMillis());
System.out.println("read data ok at " + end + ",cost:" + (end.getTime() - current.getTime()));
System.out.println("开始返回状态码");
Integer statusCode = connection.getResponseCode();
System.out.println("返回状态码:" + statusCode);
aReader.close();
connection.disconnect();
res = receivedData.toString();
return res;
} public static class MyAuthenticator extends Authenticator {
private String user = "";
private String password = ""; public MyAuthenticator(String user, String password) {
this.user = user;
this.password = password;
} protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password.toCharArray());
}
} public static void main(String[] args) throws Exception {
System.out.println(ClientSendDataSingle.send("https://localhost:8443/spdbSjptServer", "", "", "5", false, "D:/cert/tbb.jks", "12345678"));
}
}
双向认证:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.Date; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession; import com.pf.util.ClientSendDataSingle.MyAuthenticator; /**
*
* @Description https双向认证
* @author sprinng
*
*/
public class ClientSendDataDouble {
/**
*
* @param sendurl 请求地址
* @param res 返回结果
* @param sendData 参数
* @param timeOut 超时时间(min)
* @param useProxy 是否使用代理
* @param trustStorePath 服务器证书路径
* @param trustStorePwd 服务器证书密码
* @param keyStore 客户端证书路径
* @param keyStorePwd 客户端证书密码
* @param keyStoreType 客户端证书类型 如:JKS PKCS12等
* @return
* @throws Exception
*/
public static String send(String sendurl, String res, String sendData, String timeOut, boolean useProxy, String trustStorePath, String trustStorePwd, String keyStore, String keyStorePwd, String keyStoreType) throws Exception {
//设置客户端证书
System.setProperty("javax.net.ssl.keyStore", keyStore);
System.setProperty("javax.net.ssl.keyStorePassword",keyStorePwd);
System.setProperty("javax.net.ssl.keyStoreType", keyStoreType); //设置服务器证书
System.setProperty("javax.net.ssl.trustStore", trustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePwd);
URL url = new URL(sendurl);
HttpsURLConnection connection = null;
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
System.setProperty("java.protocol.handler.pkgs","sun.net.www.protocol");
HttpsURLConnection.setDefaultHostnameVerifier(hv);
Date current = new Date(System.currentTimeMillis());
System.out.println("begint to open connection at " + current);
if(useProxy){//使用代理
InetSocketAddress isa = new InetSocketAddress(PropertiesUtil.properties.getProperty("proxy_host"), Integer.parseInt(PropertiesUtil.properties.getProperty("proxy_port")));
Proxy proxy = new Proxy(Proxy.Type.HTTP, isa);
Authenticator.setDefault(new MyAuthenticator(PropertiesUtil.properties.getProperty("proxy_user"), PropertiesUtil.properties.getProperty("proxy_password")));
connection = (HttpsURLConnection) url.openConnection(proxy);
}else{
connection = (HttpsURLConnection) url.openConnection();
}
Date end = new Date(System.currentTimeMillis());
System.out.println("open connection ok at " + end + ",cost:"+ (end.getTime() - current.getTime()));
connection.setRequestProperty("Content-Type", "text/xml");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setReadTimeout(30000);
byte data[] = sendData.getBytes();
current = new Date(System.currentTimeMillis());
System.out.println("[SSLIX]notifyEai,begint to write data at " + current);
OutputStream out = connection.getOutputStream();
out.write(data);
end = new Date(System.currentTimeMillis());
System.out.println("write data ok at " + end + ",cost:" + (end.getTime() - current.getTime()));
StringBuffer receivedData = new StringBuffer();
current = new Date(System.currentTimeMillis());
System.out.println("begint to read data at " + current);
InputStreamReader inReader = new InputStreamReader(connection.getInputStream(), "UTF-8");
BufferedReader aReader = new BufferedReader(inReader);
String aLine;
while ((aLine = aReader.readLine()) != null) {
receivedData.append(aLine);
}
end = new Date(System.currentTimeMillis());
System.out.println("read data ok at " + end + ",cost:" + (end.getTime() - current.getTime()));
System.out.println("开始返回状态码");
Integer statusCode = connection.getResponseCode();
System.out.println("返回状态码:" + statusCode);
aReader.close();
connection.disconnect();
return receivedData.toString();
} public static void main(String[] args) throws Exception {
System.out.println(ClientSendDataDouble.send("https://localhost:8443/spdbSjptServer/", "", "", "5", false, "D:/cert/tbb.jks", "12345678", "D:/cert/client.p12", "12345678", "PKCS12"));
}
}
附:
import java.io.IOException;
import java.util.Properties; public class PropertiesUtil {
public static final Properties properties = new Properties();
static {
try {
properties.load(PropertiesUtil.class.getClassLoader().getResourceAsStream("config.properties"));
} catch (IOException e) {
ECommonUtil.getLog().error("初始config配置文件失败");
}
}
}
java https tomcat 单双认证(含证书生成和代码实现) 原创转载请备注,谢谢O(∩_∩)O的更多相关文章
- java实现ssl单/双向认证通信[推荐]
java实现ssl单/双向认证通信[推荐] 学习了:https://blog.csdn.net/zbuger/article/details/51695582 学习了:https://www.cnbl ...
- ionic + asp.net core webapi + keycloak实现前后端用户认证和自动生成客户端代码
概述 本文使用ionic/angular开发网页前台,asp.net core webapi开发restful service,使用keycloak保护前台页面和后台服务,并且利用open api自动 ...
- 一文读懂Https的安全性原理、数字证书、单项认证、双项认证等
本文引用了作者Smily(博客:blog.csdn.net/qq_20521573)的文章内容,感谢无私分享. 1.前言 目前苹果公司已经强制iOS应用必须使用HTTPS协议开发(详见<苹果即将 ...
- Https、OpenSSL自建CA证书及签发证书、nginx单向认证、双向认证及使用Java访问
0.环境 本文的相关源码位于 https://github.com/dreamingodd/CA-generation-demo 必须安装nginx,必须安装openssl,(用apt-get upd ...
- [转帖]nginx配置ssl加密(单/双向认证、部分https)
nginx配置ssl加密(单/双向认证.部分https) https://segmentfault.com/a/1190000002866627 nginx下配置ssl本来是很简单的,无论是去认证 ...
- linux下Tomcat+OpenSSL配置单向&双向认证(自制证书)
背景 由于ios将在2017年1月1日起强制实施ATS安全策略,所有通讯必须使用https传输,本文只针对自制证书,但目前尚不确定自制证书是否能通过appstore审核. 1.必须支持传输层安全(TL ...
- nginx配置ssl加密(单双向认证、部分https)
nginx配置ssl加密(单双向认证.部分https) nginx下配置ssl本来是很简单的,无论是去认证中心买SSL安全证书还是自签署证书,但最近公司OA的一个需求,得以有个机会实际折腾一番.一开始 ...
- Android : 关于HTTPS、TLS/SSL认证以及客户端证书导入方法
一.HTTPS 简介 HTTPS 全称 HTTP over TLS/SSL(TLS就是SSL的新版本3.1).TLS/SSL是在传输层上层的协议,应用层的下层,作为一个安全层而存在,翻译过来一般叫做传 ...
- [从零开始搭网站六]为域名申请免费SSL证书(https),并为Tomcat配置https域名所用的多SSL证书
点击下面连接查看从零开始搭网站全系列 从零开始搭网站 由于国内的网络环境比较恶劣,运营商流量劫持的情况比较严重,一般表现为别人打开你的网站的时候会弹一些莫名其妙的广告...更过分的会跳转至别的网站. ...
随机推荐
- ajax如何返回多个值
应用场景: 在前端有个ajax请求到后端后,需要返回多个变量的值,在这里使用的是Json格式作为值传递,使用eval函数来解析Json格式. 要传递的值data: var data = " ...
- ActionBar使用
在Android3.0之后,Google对UI导航设计上进行了一系列的改革,其中有一个非常好用的新功能就是引入的ActionBar,他用于取代3.0之前的标题栏,并提供更为丰富的导航效果. 一.添加A ...
- android定位
先说说手机定位的方式 1,GPS 绝大部分手机都有GPS模块,这种方式准确度是最高的,但是缺点也很明显,1,耗电高:2,绝大部分用户默认不开启GPS模块.3,从GPS模块启动到获取第一次定位数据,可能 ...
- Java多线程基础知识(五)
一. Java中的13个原子操作类 在Jdk1.5中,这个包中的原子操作类提供了一种用法简单,性能高效,线程安全的更新一个变量的方式. 1. 原子更新基本类型类 AtomicBoolean : 原子更 ...
- OpenCV成长之路(5):图像直方图的应用
正如第4篇文章所说的图像直方图在特征提取方面有着很重要的作用,本文将举两个实际工程中非常实用的例子来说明图像直方图的应用. 一.直方图的反向映射. 我们以人脸检测举例,在人脸检测中,我们第一步往往需要 ...
- BZOJ 4579: [Usaco2016 Open]Closing the Farm
Description 依次删去一个点和它的边,问当前图是否连通. Sol 并查集. 倒着做就可以了. 每次将一个点及其的边加入,如果当前集合个数大于 1,那么就不连通. Code /******** ...
- 7.5---两个正方形分成对半的直线(CC150)
最主要的思路:1,这条直线就是要把两个正方形的中点链接. 2,注意的特殊情况:中心点重合. 答案: public class Solution { public static void main(St ...
- LUA require 搜索路径指定方法
如果是一个 *.LUA 的文件, 里面用到了自己写的库, 或者第三方写的库, 但是你不想把它放到 lua 的安装目录里, 则在代码里面可以指定require搜索的路径. package.path = ...
- 【Networking】gRPC golang 相关资料
参考资料: Golang gRPC 示例: http://www.cnblogs.com/YaoDD/p/5504881.html grpc golang学习心得(1)----安装与测试: ht ...
- WCF 定制自己的签名验证逻辑
关键点: 1. 保证在客户端设置签名. client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentU ...