https://www.cnblogs.com/sprinng/p/5757795.html
自己研究的步骤
keytool -genkey -alias tbb -keyalg RSA -validity 3650 -keystore D:\ssl\cert\tbb.keystore --服务端证书,放入tomcat中
keytool -export -alias tbb -keystore D:\ssl\cert\tbb.keystore -storepass 123456 -rfc -file D:\ssl\cert\tbb.cer
keytool -import -alias mycert -file D:\ssl\cert\tbb.cer -keystore D:\ssl\cert\tbb.jks --交给客户使用
keytool -validity 36500 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore D:\ssl\cert\client.p12 --交给客户使用
keytool -export -v -alias client -keystore D:\ssl\cert\client.p12 -storetype PKCS12 -storepass 123456 -rfc -file D:\ssl\cert\client.cer --服务端认证客户端证书
keytool -import -v -alias client -file D:\ssl\cert\client.cer -keystore D:\ssl\cert\tbb.keystore -storepass 123456 --服务端认证客户端证书
以下是转载
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实现的单双人版坦克大战】是一个适合初学者的入门级编程项目,它将基础知识与实际游戏开发相结合,让学习者在实践中巩固Java语言技能。该项目的主要目标是利用Java编程语言创建一个可供单人或双人玩的坦克战斗...
在这个压缩包"随机单双.zip"中,只有一个文件名为"随机单双",这可能是某种代码、数据集或者是关于随机数生成与判断的文档。由于信息有限,我将根据一般情况来探讨随机数在IT领域的应用及其重要性。 随机数在信息...
随机单双随机单双随机单双随机单双
Java程序设计基础与进阶是学习Java编程的重要环节,涵盖了从基本语法到复杂概念的全面内容。本资源包含了基础篇和进阶篇的课后答案,对于初学者来说,是检验学习成果、解决疑惑的好帮手。不论是奇数题还是偶数题,...
每个答案的源代码都是一种实际应用的展示,通过阅读和分析,可以加深对Java语法和编程实践的理解。 复习题部分则涵盖了理论知识,包括Java语法、内存管理、垃圾回收机制、JVM工作原理等。理解这些知识有助于写出更...
在IT行业中,尤其是在软件开发领域,我们经常需要处理文件的复制和移动操作。"文件单双拷贝关键代码"这个话题聚焦于一个特定的需求:如何...通过理解和实现这样的功能,开发者可以提升在文件处理和GUI编程方面的能力。
这个补丁“升级补丁tongWeb7.0.4.2-3单双引号标签问题”旨在修复这些错误,通过更新服务器的源代码或配置,确保服务器能够正确处理含有嵌套引号的标记,无论这些标记是用户输入的还是应用程序自动生成的。...
Java网络拓扑图的实现通常是通过编程语言(如Java)与前端框架(如Vue.js)结合来完成的,以创建交互式的、可自定义的拓扑图管理界面。以下是对这些知识点的详细说明: 1. **Java网络拓扑图**:Java是多平台的编程...
本文将详细探讨Java中的单链表和双链表,以及它们的基本操作和实现细节。 首先,单链表(Single Linked List)是由一系列节点组成,每个节点包含数据元素和一个指向下一个节点的引用。在Java中,我们通常用一个类来...
在本压缩包中,"线性表实现代码(内涵顺序表静态动态分配,循环,单双链表)" 提供了线性表在不同情况下的具体实现,包括顺序表和链表两种基本形式,以及它们的不同操作方式。 1. **顺序表**: - 静态分配:在内存中...
通过分析和运行提供的源代码,不仅可以理解模块的创建和使用方法,还能掌握如何实现特定功能,如数字的单双判断以及自定义对话框的显示。这有助于提升编程技能,提高代码组织和重用性,是易语言学习者宝贵的参考资料...
3. 实现单双轴运动控制:PLC可以实现步进电机的单双轴运动控制,通过控制步进电机的角位移和速度来实现单双轴运动。 四、结论 PLC实现步进电机单双轴运动控制的方法可以满足各种自动化控制系统和机电一体化设备的...
《易语言模块数字单双详解》 易语言作为一款国内自主研发的编程语言,以其独特的“易”字命名,旨在让编程变得简单易懂。在易语言的生态系统中,各种模块扮演着重要的角色,它们提供了丰富的功能,使得开发者可以...
项目中的“基于元胞自动机的单双道交通建模Matlab仿真程序”包含了实现这些概念的Matlab代码,用户可以通过运行该程序观察交通流的动态变化。同时,"仿真程序使用说明.txt"文件应该提供了关于如何运行程序、理解输出...
在计算机科学中,数据通常以不同的进制形式存储和处理,其中最常见的包括二进制、八进制、十进制和十六进制。本话题主要关注单精度(float)和双精度(double)浮点数与十六进制之间的转换,这对于理解和调试程序,...
单双支节史密斯圆图的程序代码,有需要的可以参考一下
要实现自适应单双页功能,Turn.js提供了一些参数和方法。当书籍的页面数量是奇数时,通常会有一面没有相邻的页面,这就是所谓的单页模式。而在偶数页时,每一页都有前后两个相邻的页面,即双页模式。Turn.js可以通过...
对于单双的选择,可能是指生成的幻方是否满足某种特定的奇偶性条件,比如所有数字之和为奇数或偶数,或者幻方中奇数和偶数的位置分布等。 在实际编写程序时,为了提高效率,可以使用数学方法来优化构造过程。例如,...
单双(中边)预测单双(中边)预测单双(中单双(中边)预测边)预测单双(中边)预测