您的位置:首页 > 编程语言 > Java开发

SSL双向认证java实现

2014-05-01 10:23 363 查看


服务器端代码:

package ssl;  

  

  

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 

 */  

public class Server implements Runnable{  

  

    private static final int    DEFAULT_PORT                    = 7777;  

  

    private static final String SERVER_KEY_STORE_PASSWORD       = "123456";  

    private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "123456";  

  

    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("1223".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/ssl/kserver.keystore"), SERVER_KEY_STORE_PASSWORD.toCharArray());  

            tks.load(new FileInputStream("src/ssl/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 stub  

        start();  

    }  

}  


客户端代码:

package ssl;  

  

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 

 */  

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       = "123456";  

    private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456";  

  

    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 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/ssl/kclient.keystore"), CLIENT_KEY_STORE_PASSWORD.toCharArray());  

            tks.load(new FileInputStream("src/ssl/tclient.keystore"), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());  

  

            kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());  

            tmf.init(tks);  

  

            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);  

  

            sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(DEFAULT_HOST, DEFAULT_PORT);  

        } catch (Exception e) {  

            System.out.println(e);  

        }  

    }  

  

}  

本文通过模拟场景,介绍SSL双向认证的java实现

默认的情况下,我认为读者已经对SSL原理有一定的了解,所以文章中对SSL的原理,不做详细的介绍。
如果有这个需要,那么通过GOOGLE,可以搜索到很多这样的文章。

模拟场景:
Server端和Client端通信,需要进行授权和身份的验证,即Client只能接受Server的消息,Server只能接受Client的消息。

实现技术:
JSSE(Java Security Socket Extension
是Sun为了解决在Internet上的安全通讯而推出的解决方案。它实现了SSL和TSL(传输层安全)协议。在JSSE中包含了数据加密,服务器验证,消息完整性和客户端验证等技术。通过使用JSSE,开发人员可以在客户机和服务器之间通过TCP/IP协议安全地传输数据

为了实现消息认证。
Server需要:
1)KeyStore: 其中保存服务端的私钥
2)Trust KeyStore:其中保存客户端的授权证书
同样,Client需要:
1)KeyStore:其中保存客户端的私钥
2)Trust KeyStore:其中保存服务端的授权证书

我们可以使用Java自带的keytool命令,去生成这样信息文件
1)生成服务端私钥,并且导入到服务端KeyStore文件中
keytool -genkey -alias serverkey -keystore kserver.keystore
过程中,分别需要填写,根据需求自己设置就行
keystore密码:123456 
名字和姓氏:stone
组织单位名称:eulic
组织名称:eulic
城市或区域名称:HZ
州或省份名称:ZJ
国家代码:CN
serverkey私钥的密码,不填写和keystore的密码一致:123456
就可以生成kserver.keystore文件 
server.keystore是给服务端用的,其中保存着自己的私钥

2)根据私钥,导出服务端证书
keytool -export -alias serverkey -keystore kserver.keystore -file server.crt
server.crt就是服务端的证书

3)将服务端证书,导入到客户端的Trust KeyStore中
keytool -import -alias serverkey -file server.crt -keystore tclient.keystore
tclient.keystore是给客户端用的,其中保存着受信任的证书

采用同样的方法,生成客户端的私钥,客户端的证书,并且导入到服务端的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 clientkey -file client.crt -keystore tserver.keystore

如此一来,生成的文件分成两组
服务端保存:kserver.keystore tserver.keystore
客户端保存:kclient.keystore  tclient.kyestore

接下来,就采用JSSE,分别生成SSLServerSocket,SSLSocket
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ssl