Skip to content

Instantly share code, notes, and snippets.

@jschauma
Last active June 20, 2025 15:08
Show Gist options
  • Save jschauma/118c8ba8ae7f61cba0f45fc36091e8fe to your computer and use it in GitHub Desktop.
Save jschauma/118c8ba8ae7f61cba0f45fc36091e8fe to your computer and use it in GitHub Desktop.
BouncyCastle PQC Client
import org.bouncycastle.tls.*;
import org.bouncycastle.tls.crypto.TlsCrypto;
import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto;
import java.io.IOException;
import java.net.Socket;
import java.util.Hashtable;
import java.util.Vector;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class PQTlsClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("golang.pqc.dotwtf.wtf", 443);
TlsCrypto crypto = new BcTlsCrypto();
TlsClientProtocol clientProtocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream());
TlsClient client = new DefaultTlsClient(crypto) {
@Override
public int[] getSupportedCipherSuites() {
return new int[] {
CipherSuite.TLS_AES_128_GCM_SHA256
};
}
@Override
protected ProtocolVersion[] getSupportedVersions() {
return ProtocolVersion.TLSv13.downTo(ProtocolVersion.TLSv13);
}
@Override
public Vector<Integer> getEarlyKeyShareGroups() {
Vector<Integer> earlyGroups = new Vector<>();
earlyGroups.add(NamedGroup.x25519);
earlyGroups.add(NamedGroup.X25519MLKEM768);
return earlyGroups;
}
@Override
public Hashtable<Integer, byte[]> getClientExtensions() throws IOException {
Hashtable<Integer, byte[]> extensions = super.getClientExtensions();
Vector<Integer> namedGroups = new Vector<>();
namedGroups.add(NamedGroup.x25519);
namedGroups.add(NamedGroup.X25519MLKEM768);
TlsExtensionsUtils.addSupportedGroupsExtension(extensions, namedGroups);
return extensions;
}
@Override
public TlsAuthentication getAuthentication() throws IOException {
return new TlsAuthentication() {
@Override
public void notifyServerCertificate(TlsServerCertificate serverCertificate) {
System.out.println("Server certificate received.");
}
@Override
public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) {
return null;
}
};
}
};
clientProtocol.connect(client);
OutputStream tlsOut = clientProtocol.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(tlsOut, "UTF-8"));
writer.write("GET / HTTP/1.1\r\n");
writer.write("Host: golang.pqc.dotwtf.wtf\r\n");
writer.write("Connection: close\r\n");
writer.write("\r\n");
writer.flush();
// Read HTTP response
InputStream tlsIn = clientProtocol.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(tlsIn, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
socket.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment