How to do an SSL handshake in Java?

Corrine 31 Published: 10/16/2024

How to do an SSL handshake in Java?

To establish a secure connection using SSL/TLS in Java, you can follow these steps:

Create an SSLContext Object: The SSLContext class is used to create and manage the context of the SSL/TLS connection. You can create an instance of this class by calling its constructor with a list of trusted certificates.
SSLEngine engine = (SSLEngine) SSLContext.getInstance("TLS").createSSLEngine();

Set Trust Manager: The TrustManager interface is used to manage the trust decisions for the SSL/TLS connection. You can set a default trust manager using the setDefault() method.
engine.setDelegate(new MyTrustManager());

Handshake: Before performing any IO operations, you must establish an SSL/TLS handshake by calling the startHandshake() method on the SSLEngine object.
InputStream inputStream = // get the input stream from the server.

OutputStream outputStream = // get the output stream to the server.

engine.wrap(inputStream);

engine.startHandshake();

Get Peer's Certificate: After the handshake is complete, you can get the peer's certificate using the getPeerCertificates() method.
X509Certificate[] certificates = engine.getPeerCertificates();

for (X509Certificate certificate : certificates) {

// handle the certificate.

}

Write and Read Data: Once the SSL/TLS connection is established, you can write data to it using the output stream and read data from it using the input stream.
// Write data to the server.

outputStream.write(data);

outputStream.flush();

// Read data from the server.

byte[] buffer = new byte[1024];

int bytesRead;

while ((bytesRead = inputStream.read(buffer)) != -1) {

// handle the read data.

}

Example Code: Here's an example code that demonstrates how to establish an SSL/TLS connection and perform a handshake in Java:

import java.io.*;

import javax.net.ssl.*;

import java.security.KeyStore;

public class SslHandshakeExample {

public static void main(String[] args) throws Exception {

// Load the trust store.

KeyStore trustStore = KeyStore.getInstance("JKS");

trustStore.load(new FileInputStream("truststore.jks"), "password".toCharArray());

// Create an SSL context with the trust store.

SSLSocketFactory socketFactory = new SslSocketFactory(trustStore, "TLS");

// Establish a secure connection.

Socket socket = socketFactory.createSocket("server", 443);

// Perform the handshake.

SSLEngine engine = (SSLEngine) SSLContext.getInstance("TLS").createSSLEngine();

engine.setUseSessionTickets(true);

engine.startHandshake();

// Read and write data over the secure connection.

InputStream inputStream = socket.getInputStream();

OutputStream outputStream = socket.getOutputStream();

// Read from the server.

byte[] buffer = new byte[1024];

int bytesRead;

while ((bytesRead = inputStream.read(buffer)) != -1) {

System.out.println("Received: " + new String(buffer, 0, bytesRead));

}

// Write to the server.

outputStream.write("Hello from client!".getBytes());

outputStream.flush();

// Close the connection.

socket.close();

}

}

This code example establishes an SSL/TLS connection to a server on port 443 using a trust store. It then performs a handshake and reads and writes data over the secure connection.

Important Notes:

The SslSocketFactory class is not part of the standard Java API. You can implement your own socket factory or use a third-party library. In this example, we assume that you have a trust store with the server's certificate and private key. You need to load this trust store using the KeyStore class. The SSL/TLS connection is not actually used in this example code, but it demonstrates how to perform an SSL/TLS handshake in Java.

I hope this helps!

java ssl socket client/server example

Here's a Java example of SSL (Secure Sockets Layer) Socket Client and Server:

Server Side:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import javax.net.ssl.SSLServerSocket;

import javax.net.ssl.SSLServerSocketFactory;

import javax.net.ssl.SSLContext;

public class SSLServer {

public static void main(String[] args) throws IOException {

// Load the keystore

System.setProperty("javax.net.ssl.keyStore", "keystore.jks");

System.setProperty("javax.net.ssl.keyStorePassword", "password");

// Set up the SSL context

SSLContext sslContext = SSLContext.getInstance("TLS");

sslContext.init(null, null, null);

// Create an SSL server socket factory

SSLServerSocketFactory factory = (SSLServerSocketFactory) sslContext.getServerSocketFactory();

// Create an SSL server socket

SSLServerSocket sslSocket = factory.createServerSocket(8080);

System.out.println("SSL Server started. Listening for incoming connections...");

// Accept the first connection

Socket socket = null;

try {

socket = sslSocket.accept();

} catch (IOException e) {

System.err.println("Accept failed.");

return;

}

// Handle the client request

try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

PrintWriter writer = new PrintWriter(socket.getOutputStream(), true)) {

while (true) {

String line = reader.readLine();

if (line == null || line.equals("/quit")) {

break;

}

System.out.println("Received: " + line);

writer.println("Hello from the SSL server!");

writer.flush();

}

}

// Close the socket

if (socket != null) {

try {

socket.close();

} catch (IOException e) {

System.err.println("Close failed.");

}

}

sslSocket.close();

}

}

Client Side:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.Socket;

import javax.net.ssl.SSLContext;

import javax.net.ssl.SSLSocketFactory;

public class SSLClient {

public static void main(String[] args) throws IOException {

// Set up the SSL context

SSLContext sslContext = SSLContext.getInstance("TLS");

sslContext.init(null, null, null);

// Create an SSL socket factory

SSLSocketFactory sslFactory = sslContext.getSocketFactory();

// Create an SSL socket

Socket socket = sslFactory.createSocket("localhost", 8080);

try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

PrintWriter writer = new PrintWriter(socket.getOutputStream(), true)) {

while (true) {

System.out.print("Client: ");

String line = System.console().readLine();

writer.println(line);

writer.flush();

String response = reader.readLine();

System.out.println("Server: " + response);

if (line.equals("/quit")) {

break;

}

}

}

// Close the socket

if (socket != null) {

try {

socket.close();

} catch (IOException e) {

System.err.println("Close failed.");

}

}

}

}

To use this example, you need to create a keystore file keystore.jks and set the password as "password". Then run the server program first. After that, you can run the client program.

The client and server programs communicate using SSL/TLS protocol to encrypt and decrypt the data sent between them. The SSLContext class is used to create an SSL/TLS context for both client and server. The SSLSocketFactory class is used to create an SSL socket factory that creates secure sockets for client and server.

The example demonstrates a basic chat application where the client sends messages to the server, and the server responds with its own message. The client can type "/quit" to exit the program.