Skip to content

Instantly share code, notes, and snippets.

@djelinski
Forked from artem-smotrakov/TLSv13Test.java
Last active October 27, 2020 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save djelinski/b4543a3eb7ea66306044c08b41bba00f to your computer and use it in GitHub Desktop.
Save djelinski/b4543a3eb7ea66306044c08b41bba00f to your computer and use it in GitHub Desktop.
An example of TLS 1.3 client and server on Java. See details in https://blog.gypsyengineer.com/en/security/an-example-of-tls-13-client-and-server-on-java.html
package com.gypsyengineer.tlsbunny.jsse;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
/*
Generate self-signed ECDSA keypair with
keytool -genkeypair -alias ec -keyalg EC -keysize 256 -sigalg SHA256withECDSA -validity 365 -dname "CN=localhost,OU=Unknown,O=Unknown,L=Unknown,S=Unknown,C=Unknown" -storetype JKS -keystore ectest.jks -storepass 123456 -ext KeyUsage:c=digitalSignature,keyCertSign
Generate self-signed ECDH keypair with
keytool -genkeypair -alias ec -keyalg EC -keysize 256 -sigalg SHA256withECDSA -validity 365 -dname "CN=localhost,OU=Unknown,O=Unknown,L=Unknown,S=Unknown,C=Unknown" -storetype JKS -keystore ectest.jks -storepass 123456 -ext KeyUsage:c=keyAgreement,keyCertSign
Adjust cipher_suites as desired or comment them out entirely
Run with:
-Djavax.net.ssl.keyStore=/path/to/ectest.jks
-Djavax.net.ssl.keyStorePassword=123456
-Djavax.net.ssl.trustStore=/path/to/ectest.jks
-Djavax.net.ssl.trustStorePassword=123456
*/
public class ECCTest {
private static final int delay = 1000; // in millis
private static final String[] protocols = new String[] {"TLSv1.2"};
public static final String[] cipher_suites = { "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256" };
private static final String message =
"Like most of life's problems, this one can be solved with bending!";
public static void main(String[] args) throws Exception {
try (EchoServer server = EchoServer.create()) {
new Thread(server).start();
Thread.sleep(delay);
try (SSLSocket socket = createSocket("localhost", server.port())) {
InputStream is = new BufferedInputStream(socket.getInputStream());
OutputStream os = new BufferedOutputStream(socket.getOutputStream());
os.write(message.getBytes());
os.flush();
byte[] data = new byte[2048];
int len = is.read(data);
if (len <= 0) {
throw new IOException("no data received");
}
System.out.printf("client received %d bytes: %s%n",
len, new String(data, 0, len));
}
}
}
public static SSLSocket createSocket(String host, int port) throws IOException {
SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault()
.createSocket(host, port);
socket.setEnabledProtocols(protocols);
return socket;
}
public static class EchoServer implements Runnable, AutoCloseable {
private static final int FREE_PORT = 0;
private final SSLServerSocket sslServerSocket;
private EchoServer(SSLServerSocket sslServerSocket) {
this.sslServerSocket = sslServerSocket;
}
public int port() {
return sslServerSocket.getLocalPort();
}
@Override
public void close() throws IOException {
if (sslServerSocket != null && !sslServerSocket.isClosed()) {
sslServerSocket.close();
}
}
@Override
public void run() {
System.out.printf("server started on port %d%n", port());
try (SSLSocket socket = (SSLSocket) sslServerSocket.accept()) {
System.out.println("accepted");
InputStream is = new BufferedInputStream(socket.getInputStream());
OutputStream os = new BufferedOutputStream(socket.getOutputStream());
byte[] data = new byte[2048];
int len = is.read(data);
if (len <= 0) {
throw new IOException("no data received");
}
System.out.printf("server received %d bytes: %s%n",
len, new String(data, 0, len));
os.write(data, 0, len);
os.flush();
} catch (Exception e) {
System.out.printf("exception: %s%n", e.getMessage());
}
System.out.println("server stopped");
}
public static EchoServer create() throws IOException {
return create(FREE_PORT);
}
public static EchoServer create(int port) throws IOException {
SSLServerSocket socket = (SSLServerSocket)
SSLServerSocketFactory.getDefault().createServerSocket(port);
socket.setEnabledCipherSuites(cipher_suites);
socket.setEnabledProtocols(protocols);
return new EchoServer(socket);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment