`
raymond.chen
  • 浏览: 1426552 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

SSL安全Socket范例

 
阅读更多

    在使用Socket编写通讯程序时,通过添加对SSL的支持可以保障数据的安全和完整。Java提供了Java 安全套接字扩展——JSSE,JSSE是一个纯Java实现的SSL和TLS协议框架,抽象了SSL和TLS复杂的算法,使安全问题变得简单。使用JSSE来开发安全的Socket通讯程序需要一个证书来进行安全认证,认证支持单向认证和双向认证两种方式。

 

    在编写通讯程序之前,需要先生成证书。这里使用java自带的keytool工具生成证书。

        服务端证书:

            创建服务端keystore

                keytool -genkey -keystore server.jks -storepass 123456 -keyalg RSA -validity 365 -keypass 123456

 

            导出服务端证书

                keytool -export -keystore server.jks -storepass 123456 -file server.cer

 

            将服务端证书导入到客户端trustkeystroe

                keytool -import -keystore server_clientTrust.jks -storepass 123456 -file server.cer

 

        客户端证书:

            创建客户端keystore

                keytool -genkey -keystore client.jks -storepass 123456 -keyalg RSA -validity 365 -keypass 123456

 

            导出客户端证书

                keytool -export -keystore client.jks -storepass 123456 -file client.cer

 

            将客户端证书导入到服务端trustkeystroe

                keytool -import -keystore client_serverTrust.jks -storepass 123456 -file client.cer

 

        -keystore:指定密钥库的名称

        -storepass:指定密钥库的密码

        -keyalg:指定密钥的算法,默认值为DSA

        -validity:指定创建的证书有效期多少天(默认 90)

        -keypass:指定私钥的密码

 

 以下是范例源码:

    SSLBese源码:

public class SSLBese {
	protected static final int SERVER_PORT = 5900;

	protected static final String SERVER_JKS_FILE = "certificate/server.jks";
	protected static final String SERVER_TRUST_JKS_FILE = "certificate/serverTrust.jks";
	
	protected static final String CLIENT_JKS_FILE = "certificate/client.jks";
	protected static final String CLIENT_TRUST_JKS_FILE = "certificate/clientTrust.jks";
	
	protected static final String STOREPASS = "123456";	//密钥库的密码
	protected static final String KEYPASS = "123456";	//私钥的密码
	
	protected static int AUTH_MODULE = 2;	//认证模式:0-非SSL认证,1-单向SSL认证,2-双向SSL认证
	
	protected String read(InputStream is) throws Exception {
		BufferedInputStream in = new BufferedInputStream(is);
        byte[] buffer = new byte[1024];
        in.read(buffer);
        return new String(buffer, "UTF-8");
	}
	
	protected void write(OutputStream os, String msg) throws Exception {
		BufferedOutputStream out = new BufferedOutputStream(os);
        out.write(msg.getBytes("UTF-8"));  
        out.flush();
	}
}

  

    SSLServer源码:

public class SSLServer extends SSLBese{
	private ServerSocket serverSocket;
	
	public void start(){
        try {
    		init();
    		
            Socket socket = serverSocket.accept();
            
            String remoteAddress = socket.getRemoteSocketAddress().toString();
            System.out.println("客户端连接:" + remoteAddress);
    		
    		while (true) {
				//read
				String recMsg = read(socket.getInputStream());
				System.out.println(recMsg);

    			//write
				String msg = "Server received!";
				write(socket.getOutputStream(), msg);
            } 
    		
        } catch (Exception ex) {  
            ex.printStackTrace();  
        }
	}
	
	private void init() throws Exception {
		if(serverSocket != null){
			serverSocket.close();
			serverSocket = null;
		}
		
		if(AUTH_MODULE == 0){
			createServerSocket();
		}else{
			createSSLServerSocket();
		}
		
        System.out.println("启动监听服务[" + SERVER_PORT + "] ...");
	}
	
	private void createServerSocket() throws Exception {
		serverSocket = new ServerSocket();
		serverSocket.setReuseAddress(true);
		serverSocket.bind(new InetSocketAddress(SERVER_PORT));
	}

	private void createSSLServerSocket() throws Exception {
		//服务端私钥
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");		//创建密钥管理器
        KeyStore ks = KeyStore.getInstance("JKS");	//创建密钥库
        ks.load(new FileInputStream(SERVER_JKS_FILE), STOREPASS.toCharArray()); //加载私钥  
        keyManagerFactory.init(ks, STOREPASS.toCharArray());
        KeyManager[] kms = keyManagerFactory.getKeyManagers();
        
        //客户端的授权证书(客户端公钥)
        TrustManager[] tms = null;
        if(AUTH_MODULE == 2){
	        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");	//信任管理器
	        KeyStore tks = KeyStore.getInstance("JKS");
	        tks.load(new FileInputStream(CLIENT_TRUST_JKS_FILE), STOREPASS.toCharArray());
	        trustManagerFactory.init(tks);  
	        tms = trustManagerFactory.getTrustManagers();
        }
        
		SSLContext ctx = SSLContext.getInstance("TLSV1"); 
        ctx.init(kms, tms, null);
        
        serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket();
        ((SSLServerSocket)serverSocket).setEnabledCipherSuites(((SSLServerSocket)serverSocket).getSupportedCipherSuites());
        ((SSLServerSocket)serverSocket).setUseClientMode(false);
        
        if(AUTH_MODULE == 2){
        	((SSLServerSocket)serverSocket).setNeedClientAuth(true); //验证客户端证书
        }else{
        	((SSLServerSocket)serverSocket).setNeedClientAuth(false);
        }
        
        serverSocket.setReuseAddress(true); //是否允许重用绑定端口
        serverSocket.bind(new InetSocketAddress(SERVER_PORT));
        
        System.out.println("启用SSL安全认证");
	}
	
	public static void main(String[] args) {
		SSLServer server = new SSLServer();
		server.start();
	}
}

  

    SSLClient源码:

public class SSLClient extends SSLBese{	
	private String serverIp;
	private int serverPort;
	private Socket socket;
	
	public SSLClient(String serverIp, int serverPort){
		this.serverIp = serverIp;
		this.serverPort = serverPort;
	}
	
	public void execute(){
		try {
			init();

			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			
			while(true){
				//write
				String msg = "now time is " + sdf.format(new Date());
				write(socket.getOutputStream(), msg);
				
				//read
				String recMsg = read(socket.getInputStream());
				System.out.println(recMsg);
	            
	            TimeUnit.MILLISECONDS.sleep(1000);
			}
            
        } catch (Exception ex) {  
        	ex.printStackTrace();
        } finally {
        	if(socket != null){
        		try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
        	}
        }
	}
	
	private void init() throws Exception {
		if(AUTH_MODULE == 0){
			createSocket();
		}else{
			createSSLSocket();
		}
	}
	
	private void createSocket() throws Exception {
		socket = new Socket(); 
        socket.setKeepAlive(true);
        socket.setTcpNoDelay(true); //TCP不延迟发送
        socket.setSoLinger(true, 0); //延迟n秒关闭Socket底层连接
        socket.setSoTimeout(10000);
        socket.connect(new InetSocketAddress(this.serverIp, this.serverPort), 6000);
	}

	private void createSSLSocket() throws Exception {
		//客户端私钥
		KeyManager[] kms = null;
		if(AUTH_MODULE == 2){
	        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
	        KeyStore ks = KeyStore.getInstance("JKS");
	        ks.load(new FileInputStream(CLIENT_JKS_FILE), STOREPASS.toCharArray()); 
	        keyManagerFactory.init(ks, STOREPASS.toCharArray());  
	        kms = keyManagerFactory.getKeyManagers();
		}
		
        //服务端的授权证书(服务端公钥)
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
        KeyStore tks = KeyStore.getInstance("JKS");
        tks.load(new FileInputStream(SERVER_TRUST_JKS_FILE), STOREPASS.toCharArray());
        trustManagerFactory.init(tks);
        TrustManager[] tms = trustManagerFactory.getTrustManagers(); 
        
		SSLContext ctx = SSLContext.getInstance("TLSV1");
        ctx.init(kms, tms, null);  

        socket = (SSLSocket)ctx.getSocketFactory().createSocket();
        ((SSLSocket)socket).setEnabledCipherSuites(((SSLSocket)socket).getSupportedCipherSuites());	//可以使用所有支持的加密套件
        ((SSLSocket)socket).setUseClientMode(true);
        socket.setKeepAlive(true);
        socket.setTcpNoDelay(true);
        socket.setSoLinger(true, 0);
        socket.setSoTimeout(10000);
        socket.connect(new InetSocketAddress(this.serverIp, this.serverPort), 6000);
	}
	
	public static void main(String[] args) {
		SSLClient client = new SSLClient("127.0.0.1", SERVER_PORT);
		client.execute();
	}
	
}

  

分享到:
评论

相关推荐

    SSL网络编程范例,服务器端

    SSL(Secure Socket Layer)是一种广泛使用的安全协议,用于在互联网上传输敏感数据,如用户名、密码和信用卡信息。它的主要目标是确保数据的机密性、完整性和身份验证。在这个"SSL网络编程范例,服务器端"中,我们...

    SSL双向验证范例

    SSL(Secure Sockets Layer)是互联网上用于保护通信安全的一种技术,主要负责加密传输数据,确保数据在客户端和服务器之间不被窃取或篡改。而SSL双向验证,也称为客户端认证,是一种加强的安全措施,它不仅要求...

    pb socket范例

    PB Socket范例主要涉及到的是Protocol Buffers(简称PB)与Socket编程的结合应用。Protocol Buffers是Google开发的一种数据序列化协议,它提供了一种高效、灵活且平台无关的方式来序列化结构化数据,常用于网络通信...

    Win CE与Windows XP Socket通讯范例

    本话题将深入探讨“Win CE与Windows XP Socket通讯范例”,这涉及到Windows CE(一种嵌入式操作系统)与Windows XP(个人计算机上的操作系统)之间的网络通信,通过Socket编程实现数据交换。以下是关于这个主题的...

    Indy10 发送邮件函数 支持GMail SSL

    SSL(Secure Socket Layer)是网络安全传输的一种标准,用于在客户端和服务器之间建立安全的连接,确保数据在传输过程中不被窃取或篡改。GMail作为Google提供的邮件服务,为了保护用户的隐私和数据安全,要求使用SSL...

    bcb 《网络编程技术及应用》范例代码.rar

    SSL/TLS协议可用于实现安全套接字层,保护数据的隐私。 9. **网络服务的实现**:如HTTP、FTP、SMTP等常见网络服务的客户端和服务器端实现,可以帮助理解网络协议的工作原理。 10. **网络编程API**:了解和熟悉...

    C#非常详细的网络通讯范例源码

    C#提供了SSL/TLS协议支持,可以使用SslStream类为网络通信提供加密,以确保数据的安全传输。 10. **性能优化** 为了提升服务器的性能,可以使用多线程或多进程模型来处理客户端请求,或者使用异步I/O,以避免阻塞...

    java即时通讯im源码范例合集nw(由浅入深代码范例和详细说明).docx

    9. **安全性和认证**:IM 系统通常需要用户身份验证,使用 SSL/TLS 加密通信,以保护用户隐私和数据安全。 10. **心跳机制**:为了检测网络连接是否中断,客户端和服务器之间会定期交换心跳包,保持连接活跃。 11....

    java即时通讯im源码范例(由浅入深代码范例和详细说明).docx

    5. **安全通信**:为了保护用户的隐私和消息的安全,即时通讯系统通常使用 SSL/TLS 进行加密通信,防止数据在传输过程中被窃取或篡改。 6. **多用户支持与群组管理**:在 IM 系统中,用户可能需要与多个其他用户...

    UDP-EX,网络,通信,UDP,开发,范例

    开发者可能需要结合使用IPsec、TLS/SSL或其他加密技术来保护数据的安全。 8. **跨平台兼容性**:UDP开发示例可能需要在不同操作系统和硬件平台上运行,因此需要关注跨平台兼容性问题,确保代码能在各种环境下正常...

    openssl-1.0.0a

     SSL是Secure Socket Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。Netscape公司在推出第一个Web浏览器的同时,提出了SSL协议标准,目前已有3.0版本。SSL采用公开密钥技术。其目标是保证两个...

    OpenSSL-1_0_0d_Win32

    OpenSSL的应用程序是基于OpenSSL的密码算法库和SSL协议库写成的,所以也是一些非常好的OpenSSL的API使用范例,读懂所有这些范例,你对OpenSSL的API使用了解就比较全面了,当然,这也是一项锻炼你的意志力的工作。...

    Delphi7网络应用开发源代码

    10. **安全通信**:SSL/TLS协议用于加密通信,确保数据的安全传输。源代码可能包含使用Indy的TIdSSLComponent组件实现HTTPS连接的示例。 通过学习和研究这些源代码,开发者可以深入理解Delphi 7的网络编程机制,...

    网络编程技术及应用

    例如,HTTPS协议就是结合了HTTP和SSL/TLS协议,为网络通信提供了安全的数据传输。 此外,《网络编程技术及应用》的课程可能还会介绍网络编程的一些高级话题,如负载均衡、分布式系统、网络爬虫的实现、P2P技术以及...

    Windows网络编程技术中文版(上)

    6. **网络安全**:Windows网络编程也需考虑安全问题,如加密传输(SSL/TLS)、身份验证(如NTLM、Kerberos)以及防止拒绝服务攻击等。 7. **网络编程范例**:书中可能包含服务器端和客户端的示例代码,如简单的TCP...

    java源码包---java 源码 大量 实例

    Java Socket 聊天通信演示代码 2个目标文件,一个服务器,一个客户端。 Java Telnet客户端实例源码 一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例...

    java源码包2

    Java Socket 聊天通信演示代码 2个目标文件,一个服务器,一个客户端。 Java Telnet客户端实例源码 一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例...

    java源码包3

    Java Socket 聊天通信演示代码 2个目标文件,一个服务器,一个客户端。 Java Telnet客户端实例源码 一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例...

    java源码包4

    Java Socket 聊天通信演示代码 2个目标文件,一个服务器,一个客户端。 Java Telnet客户端实例源码 一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例...

    JAVA上百实例源码以及开源项目

    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源代码...

Global site tag (gtag.js) - Google Analytics