Library / SDK
tls-attacker/TLS-Attacker avatar
tls-attacker/TLS-Attacker

TLS-Attacker: driving a TLS stack by hand to test what a client or server will accept

TLS-Attacker is a Java-based framework for analyzing TLS libraries. It can be used to manually test TLS clients and servers or as as a software library for more advanced tools.

880 stars146 forksJavaApache-2.0

At a glance

What is it?
TLS-Attacker is a Java framework for analysing TLS libraries, built around the idea that a protocol message flow is a program you write rather than a handshake you hope for. It ships a client, a server, a man-in-the-middle prototype and a trace inspector, and it is explicitly a research tool with no GUI and no pass or fail lights.
Who is it for?
Adopt TLS-Attacker when you are writing a TLS implementation and need to know how it behaves when the peer sends something unusual, or when you are auditing an existing stack and want recorded, repeatable message flows. Do not reach for it as a general vulnerability scanner or as a way to test a third-party server you do not own.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What TLS-Attacker replaces: the assumption that a handshake is a conversation

The usual way to test a TLS implementation is to connect a client to a server and watch what happens. That model has a hard limit. It only tells you whether the happy path works, because the client decides what to send. If your library mishandles a malformed ServerHello, a renegotiation it did not expect, or a sequence of extensions in an unusual order, a well-behaved peer will never produce that case.

TLS-Attacker takes the opposite position. The README describes it as a Java-based framework for analysing TLS libraries that is able to send arbitrary protocol messages in an arbitrary order to the TLS peer and define their modifications using a provided interface. The developer writes the flow explicitly, so the flow can contain things no real server would send.

The audience is stated plainly and twice. It is a research tool intended for TLS developers and pentesters, and the README adds the warning that there is no GUI and no green or red lights. That sentence sets expectations for everything else: this is a framework you drive from code, not a tool you point at a host and read a report from. The description also notes the second mode of use, as a software library embedded in a larger tool that needs finer control than a client or server binary gives you.

WorkflowTraces: a TLS handshake expressed as a list of actions

The core abstraction is the WorkflowTrace, which the README describes as the concept used to define a TLS message flow. A WorkflowTrace is a list of actions, and those actions are executed one after the other. In a typical flow you need only two of them, a SendAction and a ReceiveAction, but the framework implements many more action types, and the full list with explanations is in the Wiki.

Writing the flow in Java looks like this:

java
Config config = Config.createConfig();
WorkflowTrace trace = new WorkflowTrace();
trace.addTlsAction(new SendAction(new ClientHelloMessage()));
trace.addTlsAction(new ReceiveAction(new ServerHelloMessage()));
State state = new State(config, trace);
DefaultWorkflowExecutor executor = new DefaultWorkflowExecutor(state);
executor.executeWorkflow();

Four objects carry the weight. Config holds the settings, the trace holds the actions, State ties them together, and the executor runs the list. Because the flow is data rather than a hardcoded sequence of calls, it can be recorded, edited and replayed, which is what the TraceTool module exists for: inspecting and modifying workflow traces.

The same flow can also be written as XML, which matters for a tool whose purpose is to reproduce a specific failure on demand. The README's XML example shows a Send action with a ClientHello carrying four extensions, a Receive action expecting ServerHello, Certificate and ServerHelloDone, and further Send and Receive actions for the key exchange and the finish. A Java developer writes the trace in Java, and the README notes that people who dislike Java can drive a customised protocol from that XML structure instead.

Building the framework with Maven and JDK 21

Compiling and running TLS-Attacker needs Java and Maven, and the README specifies that the project currently needs Java JDK 21. On Ubuntu Maven comes from the system package manager:

bash
$ sudo apt-get install maven

Then you clone the repository and build it from the TLS-Attacker directory:

bash
$ git clone https://github.com/tls-attacker/TLS-Attacker.git
$ cd TLS-Attacker
$ mvn clean install

If you are in a hurry, the README offers a way to skip the test phase:

bash
$ mvn clean install -DskipTests=true

The built jar files land in the apps folder, which is where every runtime example is launched from.

There is a second installation route for people who want TLS-Attacker as a dependency rather than a tool they run. The README gives the Maven coordinates to paste into a pom.xml, and the type is pom rather than jar, which matters when you add it to a build:

xml
<dependency>
    <groupId>de.rub.nds.tls.attacker</groupId>
    <artifactId>tls-attacker</artifactId>
    <version>7.0.0</version>
    <type>pom</type>
</dependency>

The version in that snippet is 7.0.0. Since the project also tags releases beyond that number, check which version you actually want to depend on before copying the block.

Running the client and server examples against a local test server

TLS-Attacker ships demo applications, and the README is direct about their value: they give easy access to the functionality, though the framework reaches its full potential when used as a programming library.

The client example connects to a host and port:

bash
$ cd apps
$ java -jar TLS-Client.jar -connect [host:port]

The server example listens on a port instead:

bash
$ java -jar TLS-Server.jar -port [port]

For a target to test against, the README suggests an OpenSSL test server and is emphatic about one point: please do not use public servers. The setup runs from the resources directory and the keygen.sh script has to have been run first, since the command refers to key files the repository does not ship ready to use:

bash
$ cd TLS-Attacker/resources
$ openssl s_server -key rsa1024key.pem -cert rsa1024cert.pem

That server listens on port 4433, and the client connects to it the same way:

bash
$ cd TLS-Attacker/apps
$ java -jar TLS-Client.jar -connect localhost:4433

The cipher suite and protocol version can be forced on the command line, which is how you narrow a test down to one algorithm:

bash
$ java -jar TLS-Client.jar -connect localhost:4433 -cipher TLS_RSA_WITH_AES_256_CBC_SHA -version TLS11

The maven module map and what each one is for

The repository is split into several Maven projects, and the README's list describes a tool with more ambitions than a single client binary.

TLS-Core is the protocol stack and what the README calls the heart of TLS-Attacker. TLS-Client and TLS-Server are the example applications. TLS-Mitm is described as a prototype for man-in-the-middle workflows, and the word prototype is doing real work there: it signals an area of the tool that is less settled than the core. TLS-Proxy is for using TLS-Attacker with SSLSockets, which is the path for testing code that uses the JDK's socket abstraction rather than raw sockets. TraceTool inspects and modifies TLS-Attacker workflow traces, and Transport holds the utilities for lower layers, which is where the difference between a TLS-over-TCP test and a TLS-over-something-else comes from. Utils collects general utility classes.

The top-level directory listing matches that structure, with each module present as its own directory alongside a shared pom.xml, a resources folder holding the test keys and configuration, and a Jenkinsfile for continuous integration.

For a developer, the practical question is where to write code. Anything that defines or runs a flow belongs against TLS-Core, since the State, Config and action classes are what a trace is made of, and TraceTool is what you reach for when the failure you are chasing is in the recorded sequence rather than in the exchange itself.

Protocol coverage, and the caveat the README puts next to it

The feature list is long. TLS-Attacker supports SSL 3, and TLS 1.0 through RFC-2246, 1.1 through RFC-4346, 1.2 through RFC-5246 and 1.3 through RFC-8446. SSL 2 is marked as partially supported. Key exchange covers (EC)DH(E), RSA, PSK, SRP, GOST and ANON, and the cipher suite list spans CBC, AEAD and stream ciphers including AES, CAMELLIA, DES, 3DES, IDEA, RC2, ARIA, GOST_28147_CNT_IMIT, RC4, SEED and NULL. The README counts roughly 300 cipher suites and about 30 extensions.

Beyond the crypto, it handles both client and server roles, HTTPS, workflows with more than two parties, sockets, TLS 1.3 0-RTT, STARTTLS, and Tokenbinding both at the EC level and over HTTP.

The caveat sits directly under the client example in the README, and it is worth reading before you draw conclusions from a failed handshake. If the handshake fails it is probably because no concrete cipher suite was specified, because TLS-Attacker does not completely respect server selected cipher suites. In other words, the tool does not always take the peer's preference at face value, which is exactly what makes it useful against a buggy implementation and exactly what makes it surprising when you first run it.

That behaviour is also the reason the workflow model exists. When a default client cannot be steered, you write the trace.

Where TLS-Attacker is the wrong tool

The most important limitation is stated in the README's own note: there is no GUI and no green or red lights. There is no scan report, no severity rating and no list of findings. If you need to show a colleague or a manager a verdict, you have to build that output yourself, and the framework will not tell you whether the behaviour you triggered is a vulnerability, only that it happened.

The second limit is scope of the target. The tool sends arbitrary messages to a TLS peer, so it is a testing instrument pointed at a stack you own or are authorised to test. The README's advice not to use public servers signals the intent, and a flow that deliberately violates the protocol is precisely the kind of traffic that triggers intrusion detection on a network you do not control.

Third, there is a deliberate asymmetry between the protocol coverage and the maturity of each area. SSL 2 is partially supported, and TLS-Mitm is called a prototype in the module list. The list of cipher suites and extensions is broad, but breadth and depth are different properties, and the README does not claim every one of those combinations is fully exercised.

Finally, the tool is a research instrument in its language and its shape. It is written in Java, it expects a Maven build, and it expects you to write code for anything non-trivial. For a quick check of whether a server negotiates a particular cipher suite, that is a lot of ceremony.

TLS-Attacker against a scripted socket client and against OpenSSL's own tools

The realistic alternatives come in two shapes, and both are worth comparing.

The first is a hand-written client script. You open a socket, write the bytes of a ClientHello, read the answer, and print it. That approach is fast to start and gives you total control over the bytes on the wire. The difference in approach is what you give up: you end up reimplementing record layer framing, the handshake state machine and the crypto, and every one of those reimplementations is a source of bugs that look like findings. TLS-Attacker hands you a protocol stack that already implements SSL 2 through TLS 1.3, the cipher suites and the extensions, and lets you write only the flow. You also get the trace recorded, which a script gives you only if you build the recording yourself.

The second alternative is OpenSSL's own tooling, which the README itself uses as the test target. The s_server command starts a real, working TLS server, and it will negotiate correctly with any conforming client. The difference is the opposite one: OpenSSL is a correct implementation, TLS-Attacker is a controllable one. Against a correct server, TLS-Attacker tells you what happens when the peer behaves unusually. Against OpenSSL, you are checking that your client works with a server that works.

The mixed mode is where TLS-Attacker earns its keep, and TLS-Proxy points at it. When your code uses the JDK SSLSockets layer, TLS-Proxy lets you drive that layer from a workflow trace, so you can send a deliberately malformed message through a stack that is otherwise a normal socket API. That is a capability neither a script nor OpenSSL gives you, and it is the reason the project describes itself as a framework for analysing TLS libraries rather than as a fuzzing tool.

Editorial conclusion

Adopt TLS-Attacker when you are writing a TLS implementation and need to know how it behaves when the peer sends something unusual, or when you are auditing an existing stack and want recorded, repeatable message flows. Do not reach for it as a general vulnerability scanner or as a way to test a third-party server you do not own. Verify first that you have JDK 21 and Maven available, that the generated key material from keygen.sh exists in resources, and that the cipher suite you force with -cipher matches what your implementation actually supports.

Frequently asked questions

How do I compile and run TLS-Attacker?

The README says you need Java and Maven, and that the project currently needs Java JDK 21. Clone the repository, run mvn clean install from the TLS-Attacker directory, and the built jars end up in the apps folder.

How do I define a custom TLS message flow in TLS-Attacker?

A flow is a WorkflowTrace, a list of actions executed in order, and you build one in Java with SendAction and ReceiveAction or in XML with Send and Receive elements. The README notes that many more action types are implemented beyond those two.

Which TLS versions and cipher suites does TLS-Attacker support?

The README lists SSL 3 and TLS 1.0 through 1.3 with their RFC numbers, and marks SSL 2 as partially supported. It counts roughly 300 cipher suites and about 30 extensions, and you can force a specific one with the -cipher and -version parameters of the client application.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. Releases
  5. tls-attacker/TLS-Attacker on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tls-attacker-tls-attacker.svg)](https://hysenlabs.com/projects/tls-attacker-tls-attacker)

Was this useful?