A java implementation of Enigma, and a modern attack to decrypt it.

Related tags

Security enigma
Overview

Java Enigma

This is a Java implementation of an Enigma machine, along with code that attempts to break the encryption. This code is associated with an upcoming Computerphile video.

The Enigma Machine

An enigma machine is a mechanical encryption device that saw a lot of use before and during WW2. This code simulates a 3 rotor enigma, including the 8 rotors commonly seen during the war.

Creating a Java Enigma

The code itself is fairly straightforward. You can create a new enigma machine using a constructor, for example:

enigmaMachine = new Enigma(new String[] {"VII", "V", "IV"}, "B", new int[] {10,5,12}, new int[] {1,2,3}, "AD FT WH JO PN");

Rotors and the reflector are given by their common names used in the war, with rotors labelled as "I" through to "VIII", and reflectors "B" and "C". I've not implemented every variant, such as the thin reflectors seen in naval 4-rotor enigma. You could easily add these if you liked. Starting positions and ring settings are given as integers 0-25 rather than the A-Z often seen, this is just to avoid unnecessary mappings. The majority of the code here treats letters as 0-25 to aid indexing. Plugs are given as a string of character pairs representing steckered partners. If you don't wish to use a plugboard, "" or null is fine.

Encrypting and Decrypting

Given an enigma instance, encryption or decryption is performed on character arrays of capital letters [A-Z]. Simply to save time I've not done a lot of defensive coding to remove invalid characters, so be careful to only use uppercase, or to strip unwanted characters out of strings. Here is an encryption example using the enigma machine above:

char[] plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
char[] ciphertext = enigmaMachine.encrypt(plaintext);
String s = new String(ciphertext); // UJFZBOKXBAQSGCLDNUTSNTASEF

You can quickly check everything is working by running the tests found in the EnigmaTest.java file.

How it works

Throughout the enigma machine, letters A-Z are represented as integers 0-25. Most of the components, the rotors, reflector and plugboard are treated as arrays that map values 0-25 to a different set of values 0-25. Encrypting or decrypting is simply a case of passing a value through these arrays in turn. What makes enigma trickier is that the arrays rotate, and that they can have different starting or ring positions. For efficiency in this implementation I keep the arrays fixed, and simulate rotation by shifting the index in and out of each rotor. Before each character is encrypted the rotors rotate, sometimes causing the neighbouring rotors to also rotate, this is handled by the rotate() function. Enigma has a quirk whereby the middle rotors moves twice when it turns the left-most rotor. This is called double stepping, and is also implemented here.

Breaking a Code

Breaking an enigma message here comes down to decrypting a ciphertext with all possible rotor configurations and seeing which output looks the best. We measure best here using a fitness function.

Fitness functions

The code makes a number of fitness functions available that can be used to measure how close a test decryption is to English text. Each works similarly, some work better than others. You can test to see which work best for a given message. The fitness functions are:

  • Index of coincidence. The probability of any random two letters being identical. Tends to be higher for proper sentences than for random encrypted text
  • Bi / Tri / Quad grams. The probability of a sentence measured based on the probability of constituent sequences of characters. Bigrams are pairs, such as AA or ST. Trigrams are triplets, e.g. THE, and so on.
  • Plaintext Fitness. This function is a known plaintext attack, comparing the decryption against all or portions of a suspected real plaintext. This is by far the most effective solution, even a few words of known plaintext will substantially increase your odds of a break even with a number of plugboard swaps.

Ciphertext Analysis

All the code required to crack enigma messages is found the analysis package, and an example (used in the Computerphile video) is in the main() method. The basic approach is as follows:

  1. Decrypt the ciphertext with every possible rotor in each position, and rotated to each starting position. All rotor ring settings are set to 0. No plugboard. For each decryption, measure the text fitness using one of the available fitness functions. Save the best performing rotor configuration.
  2. Fix the rotors, and iterate through all possible ring settings for the middle and right rotors, again testing the fitness of the decryption. You do not have to use the same fitness function as before.
  3. Fix all settings, and then use a hill climbing approach to find the best performing plugboard swaps, again measured using a fitness function.

Notes

  • The code is fairly efficient, Enigma boils down to a lot of array indexing into different rotors. This said, I didn't worry too much about speed, it's plenty fast enough. I used classes and functions rather than doing things inline, for example. Modern compilers will optimise a lot of it anyway.
  • Similarly, in the brute force key search code, for simplicity I create new enigma machines as required rather than implementing a number of specific reinitialisation functions that would be faster.
  • I've not written any kind of command line parsing here. You're welcome to add this, but i felt for a tutorial on enigma and breaking it, a step by step procedure in main was fine.

Resources

  1. For more details on enigma, the wikipedia articles are a great resource.

  2. This attack is a variant of that originally proposed by James Gillogly. His work on this is still available via the web archive here.

  3. If you'd like a more visual example of both encryption and cracking enigma codes, the Cryptool project is a great tool for this. Cryptool 2 has a great visualiser and can run cracking code similar to my own. I used cryptool to write the tests I used to make sure my own enigma implementation was working.

Comments
  • Update rotor position to be consistently 1-index

    Update rotor position to be consistently 1-index

    When trying out the sample text on some other enigma engines online (i.e. this one), the text came out slightly garbled.

    Since the text was still largely correct, I figured it must have been something in the rotor rotations.

    The specification of the rotor position and ring settings seem to be 1-indexed. In this project, the rotor position is maintained as 0-indexed, and also the turnover positions are kept as 0-indexed. Hence it misaligned with the 1-indexed starting position and ring setting.


    This change makes the rotors maintain a 1-index position consistently, without breaking the encipher method due to the modulo.

    opened by wvdhouten 13
  • Instructions aren't clear

    Instructions aren't clear

    I'm a novice, having not done any programming in 20 years. I've installed JDK, and compiled Main.java.

    When I run java com.mikepound.Main, I get:

    Exception in thread "main" java.lang.NullPointerException at java.io.Reader.(Unknown Source) at java.io.InputStreamReader.(Unknown Source) at com.mikepound.analysis.fitness.BigramFitness.(BigramFitness.java:21) at com.mikepound.Main.main(Main.java:14)

    I don't understand how to "create a java enigma" using a constructor

    "enigmaMachine = new Enigma(new String[] {"VII", "V", "IV"}, "B", new int[] {10,5,12}, new int[] {1,2,3}, "AD FT WH JO PN");"

    If you could dumb down your instructions for the absolute rookies among us, that would be awesome.

    opened by stretchkerr 6
  • When some plaintext is known?

    When some plaintext is known?

    Hi Mike,

    Love the videos, and in this case its great that you have provided the code. Brilliant!

    Anyway, I'm not a Java developer, but I'm trying to get through this with my C and Python knowledge. I was trying to see if I could get known bits of plain text to improve the matching of the settings? The idea being that once you've got the sudo text out, if you can identify strings that you think are correct, you can feed these back in.

    I tried adding this in, but I may be well off on what I'm doing here (Java at least part of the barrier). Any chance of an example involving some plain text, and how it might improve finding the settings?

    +      String[] known_str=new String[] {"PROPOSE", "CONSIDER", "QUESTION"};
    +      int[] intArray = new int[] { 1, 10, 21};
            FitnessFunction ioc = new IoCFitness();
            FitnessFunction bigrams = new BigramFitness();
            FitnessFunction quadgrams = new QuadramFitness();
     +     FitnessFunction knownplain = new KnownPlaintextFitness(known_str, intArray);
    

    Oh, and another quick question, in your example decrypted text, it looked (although its not fully decoded) like there are no spaces, I know that Enigma didn't have spaces, but I've read other places that someone could use X. Is the presence of Xs as spaces or something else a vulnerability to the encoding? Colin

    opened by byteduty 3
  • NOT A ISSUE - more of a comment/thanks

    NOT A ISSUE - more of a comment/thanks

    Hello; First of all I want to say that - Computerphile - is amazing, and You are Extremely Good at Explaining things! I always watch videos with you in them; And this enigma git, is just - amazing.

    Great work! Keep it up! And,

    Have a Great Corona-Free Year!

    //W

    opened by loneicewolf 1
  • Project won't compile on a machine without junit 5 precached on mavenLocal

    Project won't compile on a machine without junit 5 precached on mavenLocal

    Per https://github.com/mikepound/enigma/blob/main/EnigmaLib.iml#L15, you need the libs on your mavenLocal to compile the project. Delete (or, less destructive, rename) your ~/.m2 folder and the project won't compile anymore.

    I recommend using Gradle or even Maven to provide dependencies.

    opened by NinoDLC 0
  • Use more Java features (OOP / enum), split Rotor class, rename 'ringSettings'

    Use more Java features (OOP / enum), split Rotor class, rename 'ringSettings'

    Firstly, I'd like to thank you for your videos and I was delighted to see you abord the infamous Enigma topic. Great topic!

    I've tried to improve your code by using some OOP features of Java, as well as enums, while remaining "readable" for a non-Java user and keeping your code style intact.

    • Enums are great to represent different static configurations, so I "extracted" them when I could: RotorType and Reflector for example.
    • RotorState represents the state of the (3) rotors the Enigma is using: the type (created from I to VIII), the ringOffset (created from 0 to 25), and the mutable field rotorPosition (mutating from 0 to 25 during the object lifecycle).
    • I mutualized code in the Plugboard class to compute both the wiring and unpluggedCharacters field at once
    • I improved a bit the printing of the execution time because I was bored while the program was running 😁
    • I renamed variables where I could see fit (coherence with the rest of the code, more detailed, etc)
    • I removed unused imports on files I modified and removed a few dead code
    • I fixed https://github.com/mikepound/enigma/issues/5
    • I used private/public and final keywords as much as I could to be explicit about variable visibility and mutability (it personnaly helps me a lot when reading a new code)
    opened by NinoDLC 0
  • How works the generation of Single/Bigrams/Trigrams/Quadgrams

    How works the generation of Single/Bigrams/Trigrams/Quadgrams

    Hello,

    I am trying to use your code on a french ciphertext, so i need to change the values in "/resources/data" to make it work. Unfortunately, i don't understand how did you generate the score for Single/Bi-grams/Tri-grams and quad-grams. I suppose you use an English sample text to generate those value, and if so, it would be great if i could have the source code for this particular part.

    Thanks by advance !

    opened by Rlvx 1
  • Sorting twice?

    Sorting twice?

    At the end of findRotorConfiguration, the keySet is sorted in reverse order, then when the keySet.stream() is returned, it is also sorted in reverse order. It doesn't seem like the .sorted() would be needed on the returned stream() since the keySet is already sorted.

    FYI: On my M1 Mac mini with 8 cores, the optimized version runs in about 4.3 seconds.

    opened by PavloMcBlister 1
Owner
Michael Pound
Assistant Professor in Computer Science
Michael Pound
The samples of RMI&JNDI Attack

RMI-JNDI-Attack-Samples The samples of RMI&JNDI attack RMI Client Attack Server Server Attack Client Registry Attack Client Registry Attack Server Cli

F4DE@Syclover 7 Aug 24, 2022
Stops double clicks from impacting a player's knockback by only allowing the attack packet to be processed only once per tick per player

Stops double clicks from impacting a player's knockback by only allowing the attack packet to be processed only once per tick per player. It also moves the damage tick check to execute as soon as possible.

Jaiden 2 Oct 28, 2022
Open Source Identity and Access Management For Modern Applications and Services

Keycloak Keycloak is an Open Source Identity and Access Management solution for modern Applications and Services. This repository contains the source

Keycloak 14.6k Jan 5, 2023
JSON Web Token (JWT) implementation for Java with support for signatures (JWS), encryption (JWE) and web keys (JWK).

Nimbus JOSE+JWT Nimbus JOSE+JWT is a popular open source (Apache 2.0) Java library which implements the Javascript Object Signing and Encryption (JOSE

Connect2ID 35 Jul 1, 2022
Java implementation in the console of the classic boardgame Battleship (Batalha Naval in Portuguese)

Batalha-Naval Projeto final do modulo Java-Básico do curso Full-Stack organizado pelo Grupo Santander em parceria com a Let's Code Status: Developing

Rafael Oliveira 3 Apr 11, 2022
A small and easy-to-use one-time password generator library for Java according to RFC 4226 (HOTP) and RFC 6238 (TOTP).

OTP-Java A small and easy-to-use one-time password generator for Java according to RFC 4226 (HOTP) and RFC 6238 (TOTP). Table of Contents Features Ins

Bastiaan Jansen 106 Dec 30, 2022
Examples and HowTos for BouncyCastle and Java Cryptography Extension (JCE)

CryptographicUtilities Examples and HowTos for BouncyCastle and Java Cryptography Extension (JCE) See class "/src/main/java/de/soderer/utilities/crypt

null 1 Dec 19, 2021
A small and easy-to-use one-time password generator library for Java according to RFC 4226 (HOTP) and RFC 6238 (TOTP).

OTP-Java A small and easy-to-use one-time password generator for Java according to RFC 4226 (HOTP) and RFC 6238 (TOTP). Table of Contents Features Ins

Bastiaan Jansen 106 Dec 30, 2022
Java JWT: JSON Web Token for Java and Android

Java JWT: JSON Web Token for Java and Android JJWT aims to be the easiest to use and understand library for creating and verifying JSON Web Tokens (JW

null 8.8k Dec 30, 2022
Java Project based on Java and Encryption using Cryptography algorithms

Symmetric-Encryption-Cryptography-in-Java Java Project based on Java and Encryption using Cryptography algorithms Project Aim Develop Java program to

Muhammad Asad 6 Feb 3, 2022
A mitigation for CVE-2021-44228 (log4shell) that works by patching the vulnerability at runtime. (Works with any vulnerable java software, tested with java 6 and newer)

Log4jPatcher A Java Agent based mitigation for Log4j2 JNDI exploits. This agent employs 2 patches: Disabling all Lookup conversions (on supported Log4

null 45 Dec 16, 2022
This application can recognize the sign language alphabets and help people who do not understand sign language to communicate with the speech and hearing impaired.

Sign Language Recognition App This application can recognize the sign language alphabets and help people who do not understand sign language to commun

Mihir Gandhi 12 Oct 7, 2021
JAP is an open source authentication middleware, it is highly decoupled from business code and has good modularity and flexiblity. Developers could integrate JAP into web applications effortlessly.

?? JAP 是什么? JAP 是一款开源的登录中间件,基于模块化设计,并且与业务高度解耦,使用起来非常灵活,开发者可以毫不费力地将 JAP 集

Fujie 140 Dec 1, 2022
Make a customized list of exercises, create and save workouts, and be led through your routine. This application is currently under development.

HIIT Workout Builder ABOUT This application allows you to create and be led through customized high-intensity interval training (HIIT) sessions. The a

null 1 Nov 28, 2022
Toloka has a powerful open API, it allows you to integrate an on-demand workforce directly into your processes, and to build scalable and fully automated human-in-the-loop ML pipelines.

Toloka Java SDK Documentation Website | API Documentation | Platform Designed by engineers for engineers, Toloka lets you integrate an on-demand workf

Toloka 10 Apr 27, 2022
Time-Based One-Time Password (RFC 6238) and HMAC-Based One-Time Password (RFC 4226) reference implementations and more.

Crypto Time-Based One-Time Password (RFC 6238) and HMAC-Based One-Time Password (RFC 4226) reference implementations and more. Getting Started TOTP ge

Oliver Yasuna 1 May 12, 2022
Java binding to the Networking and Cryptography (NaCl) library with the awesomeness of libsodium

kalium - Java binding to the Networking and Cryptography (NaCl) library A Java binding to Networking and Cryptography library by Daniel J. Bernstein.

Bruno Oliveira da Silva 206 Oct 5, 2022
A library for bypassing all of Java's security mechanisms, visibility checks, and encapsulation measures via the JNI API

Narcissus: thwart strong encapsulation in JDK 16+ Narcissus is a JNI native code library that provides a small subset of the Java reflection API, whil

ToolFactory 29 Nov 3, 2022