How to do an SSL handshake in Java?
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: TheSSLContext
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.
Set Trust Manager: TheSSLEngine engine = (SSLEngine) SSLContext.getInstance("TLS").createSSLEngine();
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.
Handshake: Before performing any IO operations, you must establish an SSL/TLS handshake by calling theengine.setDelegate(new MyTrustManager());
startHandshake()
method on the SSLEngine
object.
Get Peer's Certificate: After the handshake is complete, you can get the peer's certificate using theInputStream inputStream = // get the input stream from the server.
OutputStream outputStream = // get the output stream to the server.
engine.wrap(inputStream);
engine.startHandshake();
getPeerCertificates()
method.
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.X509Certificate[] certificates = engine.getPeerCertificates();
for (X509Certificate certificate : certificates) {
// handle the certificate.
}
// 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:
TheSslSocketFactory
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.