DeepViolet is a Java API that lets you programmatically scan and analyze TLS/SSL connections. Instead of relying on external tools like openssl or online scanners, you can embed certificate analysis, cipher enumeration, risk scoring, and more directly into your own Java applications. In this post we will clone the project, build it, write a small program that scans badssl.com, and walk through the results.
Prerequisites
- Java 17 or later
- Apache Maven 3.6.3 or later
- Git
Clone and Build
Start by cloning the repository and building the JAR.
git clone https://github.com/spoofzu/DeepViolet.git
cd DeepViolet
mvn clean verify
The verify phase compiles the code, runs the full test suite, and packages the JAR. When it finishes you will have target/DeepViolet-6.1.2-SNAPSHOT.jar (or the current version) ready to use. If you only need the compiled classes without running tests, mvn clean package -DskipTests works too.
Project Structure at a Glance
The key packages to know are:
com.mps.deepviolet.api— Core interfaces:DeepVioletFactory,ISession,IEngine,TlsScannercom.mps.deepviolet.api.scoring— Risk scoring engine with 65 rules across 7 categoriescom.mps.deepviolet.api.fingerprint— TLS behavioral fingerprintingcom.mps.deepviolet.samples— Working examples you can run immediately
Scanning badssl.com — A Practical Example
badssl.com is a public test site that hosts subdomains with intentionally misconfigured TLS — expired certificates, wrong hosts, weak ciphers, and so on. It is ideal for exercising a scanner. Let us write a small program that initializes a session, pulls back cipher suites and certificate details, computes a risk score, and prints everything to the console.
Create a file called ScanBadSsl.java in src/main/java/com/mps/deepviolet/samples/:
package com.mps.deepviolet.samples;
import com.mps.deepviolet.api.*;
import java.net.URL;
public class ScanBadSsl {
public static void main(String[] args) throws Exception {
String[] targets = {
"https://expired.badssl.com/",
"https://wrong.host.badssl.com/",
"https://self-signed.badssl.com/",
"https://badssl.com/"
};
for (String target : targets) {
System.out.println("=== Scanning: " + target + " ===\n");
URL url = new URL(target);
ISession session = DeepVioletFactory.initializeSession(url);
IEngine engine = DeepVioletFactory.getEngine(session);
// Certificate information
IX509Certificate cert = engine.getCertificate();
System.out.println("Subject: " + cert.getSubjectDN());
System.out.println("Issuer: " + cert.getIssuerDN());
System.out.println("Expires: " + cert.getNotAfter());
System.out.println("Sig Alg: " + cert.getSigAlgName());
// Cipher suites
ICipherSuite[] ciphers = engine.getCipherSuites();
System.out.println("\nSupported cipher suites (" + ciphers.length + "):");
for (ICipherSuite cs : ciphers) {
System.out.printf(" %-50s %s%n",
cs.getName(), cs.getStrength());
}
// Risk score
String riskReport = engine.getRiskScore();
System.out.println("\n--- Risk Assessment ---");
System.out.println(riskReport);
// TLS fingerprint
String fingerprint = engine.getTlsFingerprint();
System.out.println("TLS Fingerprint: " + fingerprint);
// DNS security
String dns = engine.getDnsStatus();
System.out.println("DNS Security: " + dns);
System.out.println("\n");
}
}
}
Run It
Build and execute from the project root:
mvn compile exec:java \
-Dexec.mainClass="com.mps.deepviolet.samples.ScanBadSsl"
What to Expect
For expired.badssl.com you will see a certificate whose notAfter date is in the past and a risk score that flags the expiration. For wrong.host.badssl.com, the subject/SAN will not match the hostname. The self-signed.badssl.com certificate will show the same entity for both subject and issuer. And badssl.com itself should come back with a clean bill of health for comparison.
Multi-Host Parallel Scanning
For larger jobs, the TlsScanner class provides concurrent scanning with configurable thread counts, timeouts, and retry policies:
ScanConfig config = ScanConfig.builder()
.threadCount(5)
.perHostTimeoutMs(30000)
.sectionDelayMs(100)
.build();
List<IScanResult> results = TlsScanner.scan(
List.of("expired.badssl.com",
"wrong.host.badssl.com",
"self-signed.badssl.com",
"badssl.com"),
config,
new IScanListener() {
@Override
public void onHostCompleted(IScanResult r, int done, int total) {
System.out.printf("[%d/%d] %s — %s%n",
done, total, r.getURL(),
r.isSuccess() ? "OK" : r.getError().getMessage());
}
}
);
Each IScanResult gives you access to the session and engine for that host, along with timing data and details on which scan sections succeeded or failed.
Built-In Sample Programs
The repo ships with ready-to-run samples in com.mps.deepviolet.samples. A few highlights:
PrintCipherSuites— Enumerate server cipher suitesPrintCertificateChain— Retrieve and display the full certificate chainPrintRiskScore— Compute and display the TLS risk scorePrintRevocationStatus— Check OCSP, CRL, and Certificate Transparency statusPrintTlsFingerprint— Compute a behavioral TLS fingerprintPrintScan— Parallel multi-host scanningPrintAiAnalysis— AI-powered scan analysis (supports Anthropic, OpenAI, and Ollama)
Run any sample the same way:
mvn compile exec:java \
-Dexec.mainClass="com.mps.deepviolet.samples.PrintRiskScore"
Where to Go from Here
The DeepViolet repository has full Javadoc (generate with mvn javadoc:javadoc) and a validation tool you can build with mvn package -Pvalidate to compare DeepViolet results against openssl output. If you want turnkey command-line and desktop scanning tools built on this API, check out DeepVioletTools.