资讯详情

SSL连接的JAVA实现

SSL连接分为双向认证和单向认证。双向认证意味着服务器和客户端需要分别验证对方的身份。单向认证只需要客户端来验证服务器的身份。

SSL双向认证流程如下图所示:

从以上流程可以看出,为了完成双向认证,服务器和客户需要验证对方的证书,然后进行加密协商。这是基于JAVA实现服务器端和客户端的双向认证。

首先,准备服务器和客户端的相关证书:

1. 创建自签名的根密钥

openssl genrsa -out rootkey.pem 2048

2. 生成根证书

openssl req -x509 -new -key rootkey.pem -out root.crt -subj="/C=CN/ST=GD/L=GZ/O=RootCA/OU=RootCA/CN=RootCA"

3. 生成客户端密钥

openssl genrsa -out clientkey.pem 2048

4. 生成客户端证书请求文件,使用根证书签发

openssl req -new -key clientkey.pem -out client.csr -subj="/C=CN/ST=GD/L=GZ/O=BMW/OU=Vehicle/CN=Vehicle1"

5. 用根证签发客户端请求文件,生成客户端证书client.crt

openssl x509 -req -in client.csr -CA root.crt -CAkey rootkey.pem -CAcreateserial -days 3650 -out client.crt

6.包装客户端数据为pkcs12格式(client.pkcs12)

openssl pkcs12 -export -in client.crt -inkey clientkey.pem -out client.pkcs12

7.在服务器端生成密钥

openssl genrsa -out serverkey.pem 2048

8.生成服务器端证书的请求文件。请求签发证书

openssl req -new -key serverkey.pem -out server.csr -subj="/C=CN/ST=GD/L=GZ/O=BMW/OU=IT/CN=Broker"

9.服务器端请求文件由根证签发生成server.crt

openssl x509 -req -in server.csr -CA root.crt -CAkey rootkey.pem -CAcreateserial -days 3650 -out server.crt

10.打包服务器端资料为pkcs12格式(server.pkcs12 )

openssl pkcs12 -export -in server.crt -inkey serverkey.pem -out server.pkcs12

11.生成信任客户端keystore,将根证和需要信任的客户端证添加到此中keystore

keytool -importcert -alias ca -file root.crt -keystore clienttrust.jks

keytool -importcert -alias clientcert -file client.crt -keystore clienttrust.jks

12. 生成信任服务器端keystore,将根证和需要信任的服务端证添加到此中keystore

keytool -importcert -alias ca -file root.crt -keystore servertrust.jks

keytool -importcert -alias servercert -file server.crt -keystore servertrust.jks

服务器程序

以下是服务器程序

public class SSLServer  {     private SSLServerSocket sslServerSocket;     public static void main( String[] args ) throws Exception     {         SSLServer server = new SSLserver();         server.init();         System.out.println( "Server initialted!" );         server.process();     }      public void init() throws Exception {         int port = 9999;         String keystorePath = "/home/roy/projects/cert/server.pkcs12";         String keystorePass = "123456";         SSLContext context = SSLContext.getInstance("TLSv1.2");          ///加载服务器的证书Private key         KeyStore serverKeyStore = KeyStore.getInstance("pkcs12");         FileInputStream keystoreFis = new FileInputStream(keystorePath);         serverKeyStore.load(keystoreFis, keystorePass.toCharArray());         KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");         kmf.init(serverKeyStore, keystorePass.toCharArray());          ///加载信任的客户端证书keystore         String trustClientKeystorePath = "/home/roy/projects/cert/clienttrust.jks";         KeyStore trustKeyStore = KeyStore.getInstance("jks");         FileInputStream trustKeystoreFis = new FileInputStream(trustClientKeystorePath);         trustKeyStore.load(trustKeystoreFis, keystorePass.toCharArray());         TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");         tmf.init(trustKeyStore);          context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);         sslServerSocket = (SSLServerSocket)context.getServerSocketFactory().createServerSocket(port);         sslServerSocket.setNeedClientAuth(true);     }      public void process() throws Exception {         String bye = "Bye!";         byte[] buffer = new byte[50];         while(true) {             Socket socket = sslServerSocket.accept();             InputStream in = socket.getInputStream();             in.read(buffer);             System.out.println("Received: "   new String(buffer));             OutputStream out = socket.getOutputStream();             out.write(bye.getBytes());             out.flush();         }     } }

客户端程序

以下代码:

public class SSLClient {     private SSLSocket sslSocket;     public static void main( String[] args ) throws Exception     {         SSLClient client = new SSLClient();         client.init();         System.out.println( "Client initiated." );         client.process();     }      public void init() throws Exception {         String host = "127.0.0.1";         int port = 9999;         String keystorePath = "/home/roy/projects/cert/client.pkcs12";         String keystorePass = "123456";          SSLContext context = SSLContext.getInstance("TLSv1.2);

        //加载客户端的证书和private key
        KeyStore clientKeyStore = KeyStore.getInstance("pkcs12");
        FileInputStream keystoreFis = new FileInputStream(keystorePath);
        clientKeyStore.load(keystoreFis, keystorePass.toCharArray());

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
        kmf.init(clientKeyStore, keystorePass.toCharArray());

        //加载信任的服务器证书的keystore
        String trustServerKeystorePath = "/home/roy/projects/cert/servertrust.jks";
        KeyStore trustKeyStore = KeyStore.getInstance("jks");
        FileInputStream trustKeystoreFis = new FileInputStream(trustServerKeystorePath);
        trustKeyStore.load(trustKeystoreFis, keystorePass.toCharArray());
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
        tmf.init(trustKeyStore);

        context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
        sslSocket = (SSLSocket)context.getSocketFactory().createSocket(host, port);
    }

    public void process() throws Exception {
        String hello = "Hello World";
        OutputStream out = sslSocket.getOutputStream();
        out.write(hello.getBytes(), 0, hello.getBytes().length);
        out.flush();
        Thread.sleep(1000);
        InputStream in = sslSocket.getInputStream();
        byte [] buffer = new byte[50];
        in.read(buffer);
        System.out.println(new String(buffer));
    }
}

之后分别运行服务器和客户端程序,可以见到SSL的双向认证通过,建立连接并成功收发信息。

如果要实现单向认证,那么客户端的代码不需要改动,服务器端的代码改动如下:

public class SSLServer 
{
    private SSLServerSocket sslServerSocket;
    public static void main( String[] args ) throws Exception
    {
        SSLServer server = new SSLserver();
        server.init();
        System.out.println( "Server initialted!" );
        server.process();
    }

    public void init() throws Exception {
        int port = 9999;
        String keystorePath = "/home/roy/projects/cert/server.pkcs12";
        String keystorePass = "123456";
        SSLContext context = SSLContext.getInstance("TLSv1.2");

        //加载服务器的证书和Private key
        KeyStore serverKeyStore = KeyStore.getInstance("pkcs12");
        FileInputStream keystoreFis = new FileInputStream(keystorePath);
        serverKeyStore.load(keystoreFis, keystorePass.toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
        kmf.init(serverKeyStore, keystorePass.toCharArray());

        context.init(kmf.getKeyManagers(), null, null);
        sslServerSocket = (SSLServerSocket)context.getServerSocketFactory().createServerSocket(port);
        sslServerSocket.setNeedClientAuth(false);
    }

    public void process() throws Exception {
        String bye = "Bye!";
        byte[] buffer = new byte[50];
        while(true) {
            Socket socket = sslServerSocket.accept();
            InputStream in = socket.getInputStream();
            in.read(buffer);
            System.out.println("Received: " + new String(buffer));
            OutputStream out = socket.getOutputStream();
            out.write(bye.getBytes());
            out.flush();
        }
    }
}

标签: kmf磁感应直线位移传感器sunx电涡流位移传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台