大家好,欢迎来到IT知识分享网。
一、简介
SSL/TLS协议是安全的通信模式,而对于这些底层协议,如果要每个开发者都自己去实现显然会带来不必要的麻烦,正是为了解决这个问题Java为广大开发者提供了Java安全套接字扩展——JSSE,它包含了实现Internet安全通信的一系列包的集合,是SSL和TLS的纯Java实现,同时它是一个开放的标准,每个公司都可以自己实现JSSE,通过它可以透明地提供数据加密、服务器认证、信息完整性等功能,就像使用普通的套接字一样使用安全套接字,大大减轻了开发者的负担,使开发者可以很轻松将SSL协议整合到程序中,并且JSSE能将安全隐患降到了最低点。
在用JSSE实现SSL通信过程中主要会遇到以下类和接口,由于过程中涉及到加解密、密钥生成等运算的框架和实现,所以也会间接用到JCE包的一些类。如图3-1-7-2为JSSE接口的主要类图:
二、证书简介
SSL协议通信涉及密钥储存的文件格式比较多,很容易搞混,例如xxx.cer、xxx.pfx、xxx.jks、xxx.keystore、xxx.truststore等格式文件。如图3-1-7-3,搞清楚他们有助于理解后面的程序,.cer格式文件俗称证书,但这个证书中没有私钥,只包含了公钥;.pfx格式文件也称为证书,它一般供浏览器使用,而且它不仅包含了公钥,还包含了私钥,当然这个私钥是加密的,不输入密码是解不了密的;.jks格式文件表示java密钥存储器(javakey store),它可以同时容纳N个公钥跟私钥,是一个密钥库;.keystore格式文件其实跟.jks基本是一样的,只是不同公司叫法不太一样,默认生成的证书存储库格式;.truststore格式文件表示信任证书存储库,它仅仅包含了通信对方的公钥,当然你可以直接把通信对方的jks作为信任库(就算如此你也只能知道通信对方的公钥,要知道密钥都是加密的,你无从获取,只要算法不被激活成功教程)。有些时候我们需要把pfx或cert转化为jks以便于用java进行ssl通信,例如一个银行只提供了pfx证书,而我们想用java进行ssl通信时就要将pfx转化为jks格式。
三、生成证书,
keytool用法:
1.生成
keytool -genkey -alias yushan(别名) -keypass yushan(别名密码) -keyalg RSA(算法) -keysize 1024(密钥长度) -validity 365(有效期,天单位) -keystore e:\yushan.keystore(指定生成证书的位置和证书名称) -storepass (获取keystore信息的密码);回车输入相关信息即可;
2.导出(证书库导出到crt证书文件)
keytool -export -alias yushan -keystore e:\yushan.keystore -file e:\yushan.crt(指定导出的证书位置及证书名称) -storepass
3.导入(从证书文件导入到keystore或jks文件)
制作我的证书:
服务器端:
客户端:
生成文件:
四、实现SSL
服务端简单实现:
public static void main(String[] args) throws Exception {
//密钥管理器
KeyStore serverKeyStore = KeyStore.getInstance("JKS");//证书库格式
serverKeyStore.load(new FileInputStream("e:\\myserver.jks"), "".toCharArray());//加载密钥库
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");//证书格式
kmf.init(serverKeyStore, "".toCharArray());//加载密钥储存器
//信任管理器
KeyStore clientKeyStore = KeyStore.getInstance("JKS");
clientKeyStore.load(new FileInputStream("e:\\myclient.jks"), "".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(clientKeyStore);
//SSL上下文设置
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
//SSLServerSocket
SSLServerSocketFactory serverFactory = sslContext.getServerSocketFactory();
SSLServerSocket svrSocket = (SSLServerSocket) serverFactory.createServerSocket(34567);
//svrSocket.setNeedClientAuth(true);//客户端模式,服务端需要验证客户端身份
String[] supported = svrSocket.getEnabledCipherSuites();//加密套件
svrSocket.setEnabledCipherSuites(supported);
//接收消息
System.out.println("端口已打开,准备接受信息");
SSLSocket cntSocket = (SSLSocket) svrSocket.accept();//开始接收
InputStream in=cntSocket.getInputStream();//输入流
int a=in.read(new byte[102]);
//循环检查是否有消息到达
System.out.println("来自于客户端:" + a);
}
基本顺序是先得到一个SSLContext实例,再对SSLContext实例进行初始化,密钥管理器及信任管理器作为参数传入,证书管理器及信任管理器按照指定的密钥存储器路径和密码进行加载。接着设置支持的加密套件,最后让SSLServerSocket开始监听客户端发送过来的消息。
客户端实现:
public static void main(String[] args) throws Exception {
//密钥管理器
KeyStore clientKeyStore = KeyStore.getInstance("JKS");
clientKeyStore.load(new FileInputStream("e:\\myclient.jks"), "".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(clientKeyStore, "".toCharArray());
//信任管理器
KeyStore serverKeyStore = KeyStore.getInstance("JKS");
serverKeyStore.load(new FileInputStream("e:\\myserver.jks"), "".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(serverKeyStore);
//SSL上下文
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLSocketFactory sslcntFactory =(SSLSocketFactory) sslContext.getSocketFactory();
SSLSocket sslSocket= (SSLSocket) sslcntFactory.createSocket("127.0.0.1", 34567);
String[] supported = sslSocket.getSupportedCipherSuites();
sslSocket.setEnabledCipherSuites(supported);
//发送
OutputStream out=sslSocket.getOutputStream();
out.write("hello".getBytes());
}
最后谈谈信任管理器,它的职责是觉得是否信任远端的证书,那么它凭借什么去判断呢?如果不显式设置信任存储器的文件路径,将遵循如下规则:
①如果系统属性javax.net.ssl.truststore指定了truststore文件,那么信任管理器将去jre路径下的lib/security目录寻找这个文件作为信任存储器;
②如果没设置①中的系统属性,则去寻找一个%java_home%/lib/security/jssecacerts文件作为信任存储器;
③如果jssecacerts不存在而cacerts存在,则cacerts作为信任存储器。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/135127.html