SSlSocket和SSLServerSocket的学习
来源:互联网 发布:淘宝如何延迟确认收货 编辑:程序博客网 时间:2024/05/22 12:58
什么是SSLSocket
JDK文档指出,SSLSocket扩展Socket并提供使用SSL或TLS协议的安全套接字。
这种套接字是正常的流套接字,但是它们在基础网络传输协议(如TCP)上添加了安全保护层。
具体安全方面的讨论见下一篇。本篇重点关注SSLSocket及相关几个类的使用。
SSLSocket和相关类
SSLSocket来自jsse(Java Secure Socket Extension)。
(1)SSLContext: 此类的实例表示安全套接字协议的实现, 它是SSLSocketFactory、SSLServerSocketFactory和SSLEngine的工厂。
(2)SSLSocket: 扩展自Socket
(3)SSLServerSocket: 扩展自ServerSocket
(4)SSLSocketFactory: 抽象类,扩展自SocketFactory, SSLSocket的工厂
(5)SSLServerSocketFactory: 抽象类,扩展自ServerSocketFactory, SSLServerSocket的工厂
(6)KeyStore: 表示密钥和证书的存储设施
(7)KeyManager: 接口,JSSE密钥管理器
(8)TrustManager: 接口,信任管理器(?翻译得很拗口)
(9)X590TrustedManager: TrustManager的子接口,管理X509证书,验证远程安全套接字
实现技术:
JSSE(Java Security SocketExtension)
是Sun为了解决在Internet上的实现安全信息传输的解决方案。它实现了SSL和TSL(传输层安全)协议。在JSSE中包含了数据加密,服务器验证,消息完整性和客户端验证等技术。通过使用JSSE,可以在Client和Server之间通过TCP/IP协议安全地传输数据。
为了实现消息认证。
Server需要:
1)KeyStore: 其中保存服务端的私钥
2)Trust KeyStore:其中保存客户端的授权证书
Client需要:
1)KeyStore:其中保存客户端的私钥
2)Trust KeyStore:其中保存服务端的授权证书
使用Java自带的keytool命令,去生成这样信息文件:
1) 生成服务端私钥,并且导入到服务端KeyStore文件中:
2、根据私钥,导出服务器证书:keytool -export -alias serverkey -keystore kserver.keystore -file server.crt
3、将服务器证书,导入到客户端的Trust KeyStore中:keytool -import -alias serverkey -file server.crt -keystore tclient.store
采用同样的方法,生成客户端的私钥,客户端的证书,并且导入到服务端的Trust KeyStore:
1、keytool -genkey -alias clientkey -keystore kclient.keystore
2、keytool export -alias clientkey -keystore kclient.keystore -file client.crt
3、keytool -import -alias client -file client.crt -keystore tserver.keystore
将生成的tclient.keystore、tserver.keystore、kclient.keystore、kserver.keystore导入要项目:
Server代码如下:
import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.security.KeyStore;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLServerSocket;import javax.net.ssl.TrustManagerFactory;/** * * @author Leo */public class Server implements Runnable{ private static final int DEFAULT_PORT = 7777; private static final String SERVER_KEY_STORE_PASSWORD = "1234qwer?"; private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "1234qwer?"; private SSLServerSocket serverSocket; /** * 启动程序 * * @param args */ public static void main(String[] args) { Server server = new Server(); server.init();Thread thread = new Thread(server);thread.start(); } public synchronized void start() { if (serverSocket == null) { System.out.println("ERROR"); return; } while (true) { try { Socket s = serverSocket.accept(); InputStream input = s.getInputStream(); OutputStream output = s.getOutputStream(); BufferedInputStream bis = new BufferedInputStream(input); BufferedOutputStream bos = new BufferedOutputStream(output); byte[] buffer = new byte[20]; bis.read(buffer); System.out.println("------receive:--------"+new String(buffer).toString()); bos.write("yes".getBytes()); bos.flush(); s.close(); } catch (Exception e) { System.out.println(e); } } } public void init() { try { SSLContext ctx = SSLContext.getInstance("SSL"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); KeyStore ks = KeyStore.getInstance("JKS"); KeyStore tks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("src/kserver.keystore"), SERVER_KEY_STORE_PASSWORD.toCharArray()); tks.load(new FileInputStream("src/tserver.keystore"), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray()); kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray()); tmf.init(tks); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(DEFAULT_PORT); serverSocket.setNeedClientAuth(true); } catch (Exception e) { System.out.println(e); } }public void run() {// TODO Auto-generated method stubstart();}}
Client代码如下:
import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.security.KeyStore;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSocket;import javax.net.ssl.TrustManagerFactory;/** * SSL Client * * @author Leo */public class Client { private static final String DEFAULT_HOST = "127.0.0.1"; private static final int DEFAULT_PORT = 7777; private static final String CLIENT_KEY_STORE_PASSWORD = "1234qwer?"; private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "1234qwer?"; private SSLSocket sslSocket; /** * 启动客户端程序 * * @param args */ public static void main(String[] args) { Client client = new Client(); client.init(); client.process(); } public void process() { if (sslSocket == null) { System.out.println("ERROR"); return; } try { InputStream input = sslSocket.getInputStream(); OutputStream output = sslSocket.getOutputStream(); BufferedInputStream bis = new BufferedInputStream(input); BufferedOutputStream bos = new BufferedOutputStream(output); bos.write("1234567890".getBytes()); bos.flush(); byte[] buffer = new byte[20]; bis.read(buffer); System.out.println(new String(buffer)); sslSocket.close(); } catch (IOException e) { System.out.println(e); } } public void init() { try { //获取SSlContext对象 SSLContext ctx = SSLContext.getInstance("SSL"); //JSSE密钥管理器KeyManagerFactory对象 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); //信任管理器TrustManagerFactory对象 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); //密钥和证书的存储设施 KeyStore ks = KeyStore.getInstance("JKS"); KeyStore tks = KeyStore.getInstance("JKS"); //载入keystore ks.load(new FileInputStream("src/kclient.keystore"), CLIENT_KEY_STORE_PASSWORD.toCharArray()); tks.load(new FileInputStream("src/tclient.keystore"), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray()); //KeyManagerFactory对象初始化 kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray()); //TrustManagerFactory对象初始化 tmf.init(tks); //SSLContext对象初始化 ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); //创建连接sslSocket对象 sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(DEFAULT_HOST, DEFAULT_PORT); } catch (Exception e) { System.out.println(e); } }}
运行时,先启动server,在运行client,否则报错。
这样,就完成了服务端和客户端之间的基于身份认证的交互。
交互原理:
client采用kclient.keystore中的clientkey私钥进行数据加密,发送给server。
server采用tserver.keystore中的client.crt证书(包含了clientkey的公钥)对数据解密,如果解密成功,来自client,进行逻辑处理。
server采用kserver.keystore中的serverkey私钥进行数据加密,发送给client。
client采用tclient.keystore中的server.crt证书(包含了serverkey的公钥)对数据解密,如果解密成功,来自server,进行逻辑处理。
过程中,如果解密失败,证明消息来源错误,不进行逻辑处理。
- SSlSocket和SSLServerSocket的学习
- SSLServerSocket、SSLSocket简单例子
- 学习Android客户端和服务器端SSLSocket交互的总结
- Java SSLSocket的使用
- Java SSLSocket的使用
- Java SSLSocket的使用
- Java SSLSocket的使用
- Java SSLSocket的使用
- java SSLSocket的详解
- Java SSLSocket的使用
- SSLSocket的使用
- sslsocket
- SSLSocket
- SSL + Socket NIO 原理 与 SSLEngine + Naga SSLSocket 的使用
- sslsocket通信
- sslsocket实例
- 一个关于Andriod的SSL双向认证的SSLSocket库—SelevenSSLSocket
- 关于SSLSocket程序中报的那些错:connect refuse;...must be non-empty等。
- 解决 schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/context
- Google Guava官方教程(中文版)(转)
- LINUX UMASK详解
- 20150819,微软8月18日发布一个计划外安全补丁
- c# 查询 插入 access db 2007
- SSlSocket和SSLServerSocket的学习
- 设计模式-适配器模式
- git常用配置
- iOS UI初级-标签控制器
- 浅谈进程地址空间与虚拟存储空间
- Outlook HTML渲染引擎
- 超级台阶
- Service和Thread的关系
- 没有 /lib/modules/*/build 这个目录