Java数字证书与HHTPS安全通信
来源:互联网 发布:rewrite 知乎 编辑:程序博客网 时间:2024/05/16 17:17
1.Java 数字证书
JDK 自带 keytool工具,在 jdk\bin 目录下,可以用来管理秘钥库、证书数据库和私有秘钥。
秘钥库中每一项都拥有一个别名,在cmd命令行输入 keytool -help 命令可以查看该工具的使用方法
1.1 生成自己的证书并导出
(1)创建秘钥库
keytool -genkeypair -keystore myCert.certs -alias myCert
执行这个命令之后,就会在当前目录就会生成秘钥库文件 myCert.certs ,如下所示
(2)导出证书
将秘钥库的公共秘钥导出成证书,就可以给其他人或者组织使用
只不过这种个人证书,是没有经过第三方担保的,可信度不高
keytool -exportcert -keystore myCert.certs -alias myCert -file my.cer
执行完命令,在当前目录就会生成证书,证书是包含了公钥的,如下
(3)查看证书
keytool -printcert -file my.cer 结果如下所示
1.2 客户端导入证书
假设你把证书发给你的客户 Lily,现在她需要把证书导入到证书库才可以使用,Lily只需要这么操作
keytool -importcert -keystore lily.certs -alias lily -file my.cer
1.3 使用证书
(1)使用证书签名
接下来我们使用 jarsigner 这个工具,将一个文档签名,就使用你自己创建的证书来签名
jarsigner -keystore myCert.certs test.jar myCert
(2)使用证书校验
然后你可以把签名过的文档,也就是 test.jar 发送给客户端,比如就是Lily
她使用你给她的证书来校验:这个文档是否确实是你签名过的
jarsigner -verify -keystore lily.certs test.jar
如果打印出来 jar 已验证 说明认证成功
至此我们了解JDK自带的keytool和jarsigner工具,可以用来创建秘钥库,导出自己的证书
也可以发送证书给客户端使用,客户端只要导入证书,并使用证书来认证签名即可
总的来说:数字签名就是具备 不可否认性 和 完整性 的功效
2. HTTPS 协议
https协议就简单看做http协议的简单版本,他是在TCP/IP层与HTTP应用层之间
加入SSL协议,保证数据传输的安全性,因为采用加密传输,所以即使被盗窃
没有秘钥解密也是没问题的,至于https协议的握手过程,可以看书或者网上都能找到
这里要介绍的是如何把 数字证书 与 HTTPS 协议结合起来使用
2.1 Tomcat 配置SSL协议
我们知道http请求使用80端口,https则使用443端口
证书在第一步我们已经生成了,接下来我们就把数字证书配置到Tomcat服务器
打开Tomcat 的server.xml 配置文件,配置SSL服务
<Connector SSLEnabled="true" clientAuth="false"keystoreFile="C:/Users/Administrator/myCert.certs" keystorePass="123456"maxThreads="150" port="8443" protocol="HTTP/1.1" scheme="https"secure="true" sslProtocol="TLS" />
keystoreFile:秘钥库文件的地址,这是你自己在第一步就已经生成的
keystorePass:秘钥库主密码,就是你自己创建秘钥库时输入的密码
接下来,你只要创建一个Web应用,然后就可以使用https协议方式来访问了
到此为止:数字证书已经和https协议结合起来使用了
只不过浏览器访问时:仍然会提示这个证书是需要客户端自己担责的,因为这个证书没有经过第三方比如CA认证
2.2 通过SSL安全套接字来访问https服务
package com.yli.security;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.URL;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLSession;public class SSLTest { public static void main(String[] args) throws IOException { // 创建URL对象 URL myURL = new URL("https://localhost:8443/SSlWeb/index.jsp"); // 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象 HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection(); // 取得该连接的输入流,以读取响应内容 InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream()); BufferedReader r = new BufferedReader(insr); String line; while((line = r.readLine())!=null) { System.out.println(line); } }}
一般情况下,直接运行会报错,最常见的就是:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
这是因为Java的安全机制造成的:客户端的TrustStore文件中保存着被客户端所信任的服务器的证书信息。
客户端在进行SSL连接时,JSSE将根据这个文件中的证书决定是否信任服务器端的证书。
在SunJSSE中,有一个信任管理器类负责决定是否信任远端的证书,这个类有如下的处理规则:
1)若系统属性javax.net.sll.trustStore指定了TrustStore文件,那么信任管理器就去jre安装路径下的lib/security/目录中寻找并使用这个文件来检查证书。
2)若该系统属性没有指定TrustStore文件,它就会去jre安装路径下寻找默认的TrustStore文件,这个文件的相对路径为:lib/security/jssecacerts。
3)若jssecacerts不存在,但是cacerts存在(它随J2SDK一起发行,含有数量有限的可信任的基本证书),那么这个默认的TrustStore文件就是lib/security/cacerts。
在这种情况下,最简单的解决办法就是把证书导入到 jdk\jre\lib\security\caerts 证书库中
keytool -import -alias myCert_for_serverkey -file my.cer -keystore %JAVA_HOME%\jre\lib\security\cacerts
特别留意:这是要把证书导入到jdk的证书库中,输入密码是 changeit 这是jdk证书库的默认密码!!!
接下来,你再运行之前的程序,可能还会报错,不过应该是这种错误了:
java.security.cert.CertificateException: No name matching localhost found
如果不是这种错误:请你检查,你Eclipse工作空间的jdk,是不是使用刚才导入证书库的jdk呢!!!!
如果是这种错误,需要我们实现 HostnameVerifier 接口,才能正常使用,完整代码如下
package com.yli.security;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.URL;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLSession;public class SSLTest { public static void main(String[] args) throws IOException { // 创建URL对象 URL myURL = new URL("https://localhost:8443/SSlWeb/index.jsp"); // 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象 HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection(); // 设置hostname 校验 httpsConn.setHostnameVerifier(new MyHostnameVerifier()); // 取得该连接的输入流,以读取响应内容 InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream()); BufferedReader r = new BufferedReader(insr); String line; while((line = r.readLine())!=null) { System.out.println(line); } }}class MyHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String hostname, SSLSession sslSession) { if (hostname.equals("localhost")) { return true; } return false; } }
这个时候,如果你是按照步骤一步一步来实现的,应该就成功运行了,能看到输出结果
好了,简单的数字证书与签名,以及怎么使用HTTPS协议介绍到这里为止
- Java数字证书与HHTPS安全通信
- Java安全通信、数字证书及应用实践
- Java安全通信、数字证书及应用实践
- Java安全通信、数字证书及应用实践
- Java安全通信、数字证书及应用实践
- Java安全通信、数字证书及应用实践
- Java安全通信、数字证书及应用实践
- Java安全通信、数字证书及应用实践
- Java安全通信、数字证书及数字证书应用实践
- Java安全通信、数字证书及数字证书应用实践(zz)
- java安全通信、数字证书及数字证书应用实践
- Java安全通信、数字证书及数字证书应用实践
- Java安全通信、数字证书及数字证书应用实践
- Java安全通信、数字证书及数字证书应用实践
- Java安全通信、数字证书及应用实践(转)
- Java安全通信、数字证书及应用实践(转SSL证书)
- Java安全之数字证书
- Java安全(JCA/JSSE):数字证书与SSL
- 多线程 中 对多次初始化问题解决方案
- 程序员成就技术大拿之路
- day16
- OC面向对象三大特性
- wso2——(1)esb安装
- Java数字证书与HHTPS安全通信
- An Analysis of Single-Layer Networks in Unsupervised Feature Learning(精读)
- sql_学习笔记02_表
- HDU 5020 容器标记斜率
- Java环境变量配置
- VMware Horizon 6.0 (安装composer时报错)
- 你需要知道的 16 个 Linux 服务器监控命令
- HTML+CSS入门笔记一之HTML+CSS基本思想
- Python资源下载