This article describes the method of implementing SSL two-way authentication in Java. Share it for your reference, as follows:
The common SSL verification is more common. Only verify whether our server is true or correct. Of course, if the URL you are visiting is wrong at all, then no one can do it. This is called SSL one-way authentication.
But in reality, we may also verify whether the client meets the requirements, that is, issue a certificate to each of our users, and each digital certificate is unique and not public. In this way, you can ensure that the user currently accessing my server is recognized by the server and cannot be accessed by others.
Two-way authentication ensures that both the server and the client recognize each other at the first level. Then if they want to communicate, they will attach an SSL protocol to the communication protocol to ensure that the content of the communication is encrypted. Even network sniffer tools like sniffer see garbled code. In the future, I will demonstrate to you what you see with sniffer without encryption. I'm afraid you will be more vigilant this way.
The following content is excerpted from the Internet and modified after actual verification.
Simulation scenario:
When the server side communicates with the client side, authorization and identity verification are required, that is, the client can only accept messages from the Server, and the Server can only accept messages from the Client.
Implementation technology:
JSSE (Java Security Socket Extension)
It is a solution launched by Sun to solve secure communications on the Internet. It implements SSL and TSL (Transport Layer Security) protocols. The JSSE includes technologies such as data encryption, server verification, message integrity and client verification. By using JSSE, developers can safely transfer data between the client and the server via the TCP/IP protocol.
In order to implement message authentication.
Server requires:
1) KeyStore: where the private key of the server is saved
2) Trust KeyStore: It saves the client's authorization certificate
Similarly, Client requires:
1) KeyStore: where the client's private key is saved
2) Trust KeyStore: Here I recommend using the keytool command that comes with Java to generate such information files. Of course, OpenSSL is also the most popular open source SSL certificate generation. OpenSSL is written in C language, cross-system. However, we may consider the convenience of using Java programs to generate certificates in the future, and use the keytool that comes with JDK.
1) Generate the server private key and import it into the server KeyStore file
keytool -genkey -alias serverkey -keystore kserver.keystore
During the process, you need to fill in it separately and set it up according to your needs.
keystore password: 123456
First and last name: jin
Organizational unit name: none
Organization name: none
City or region name: BJ
State or province name: BJ
Country code: CN
The password of the serverkey private key is not filled in the same as the password of the keystore. Be sure to pay attention here, just press Enter without changing your password. Otherwise, if this private key cannot be applied directly in the subsequent program, an error will be reported.
You can generate the kserver.keystore file
server.keystore is used for the server, which stores its own private key.
2) Export the server certificate based on the private key
keytool -export -alias serverkey -keystore kserver.keystore -file server.crt
server.crt is the certificate on the server side
3) Import the server certificate into the client's Trust KeyStore
keytool -import -alias serverkey -file server.crt -keystore tclient.keystore
tclient.keystore is for clients, and it holds a trusted certificate.
In the same way, generate the client's private key and client's certificate, and import it into the server's 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
In this way, the generated files are divided into two groups
Server save: kserver.keystore tserver.keystore
Client save: kclient.keystore tclient.kystore
The following is to verify that the certificate we generated is available through the Java Socket communication program.
Client:
package examples.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.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 * */public class SSLClient { 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; /** * Start the client program* * @param args */ public static void main(String[] args) { SSLClient client = new SSLClient(); client.init(); client.process(); } /** * Connect to the server through the ssl socket and send a message*/ 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("Client Message".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); } } /** * <ul> * <li>The key points of ssl connection: </li> * <li>Initialize SSLSocket</li> * <li>Import the client private key KeyStore, import the client trusted KeyStore (server certificate) </li> * </ul> */ 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("E://kclient.keystore"), CLIENT_KEY_STORE_PASSWORD.toCharArray()); tks.load(new FileInputStream("E://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); } }}Server side:
package examples.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;/****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** serverkey -keystore kserver.keystore -file server.crt</li> * <li>3) Add the certificate to the trusted keystore of the client </li> * <li>keytool -import -alias serverkey -file server.crt -keystore tclient.keystore</li> * </ul> ********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* Server * */public class SSLServer { 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; /** * Start the program* * @param args */ public static void main(String[] args) { SSLServer server = new SSLServer(); server.init(); server.start(); } /** * <ul> * <li>Listen to SSL Server Socket</li> * <li> Since this program is not a demonstration of Socket listening, it simply adopts a single-threaded form, and only accepts the client's messages and returns the client's specified message</li> * </ul> */ public 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(new String(buffer)); bos.write("Server Echo".getBytes()); bos.flush(); s.close(); } catch (Exception e) { System.out.println(e); } } } } /** * <ul> * <li>The key points of ssl connection: </li> * <li>Initialize SSLServerSocket</li> * <li>Import the server private key KeyStore, and import the server trusted KeyStore (client certificate) </li> * </ul> */ 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("E://kserver.keystore"), SERVER_KEY_STORE_PASSWORD.toCharArray()); tks.load(new FileInputStream("E://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) { e.printStackTrace(); } }}For more information about Java related content, please check out the topics of this site: "Java Data Structure and Algorithm Tutorial", "Summary of Java Operation DOM Node Tips", "Summary of Java File and Directory Operation Tips" and "Summary of Java Cache Operation Tips"
I hope this article will be helpful to everyone's Java programming.