Enigma a C#


Co je Enigma?

Enigma je elektromechanický šifrovací stroj, který byl široce používán německou armádou během druhé světové války. Na rozdíl od klasických ručních šifer, Enigma kombinovala rotory, reflektor a plugboard, aby vytvořila velmi složité šifrování. Výsledkem bylo, že každý znak textu byl transformován na jiný znak a tato transformace se neustále měnila s každým stiskem klávesy.

Princip fungování Enigmy

  1. Rotory – hlavní komponenta Enigmy. Každý rotor nahrazuje písmeno jiným písmenem a po každém stisknutí klávesy se rotor mírně otočí, čímž se mění substituce.
  2. Reflektor – rotor, který odráží signál zpět přes rotory, aby umožnil obousměrné šifrování, což znamená, že stejný stroj s tímto nastavením může šifrovat i dešifrovat.
  3. Plugboard (steckerbrett) – přepojovací panel, který umožňuje dodatečné párování písmen před vstupem do rotorů, čímž se zvyšuje složitost šifry.
  4. Denní nastavení – kombinace rotorů, jejich počátečních pozic a zapojení plugboardu tvořila tzv. denní klíč, který musel být předem znám jak u odesílatele, tak u příjemce.

Bezpečnost Enigmy

Enigma byla v době svého používání považována za velmi bezpečnou, protože počet možných konfigurací byl astronomický – kombinace rotorů, jejich pořadí, počáteční pozice a plugboardu poskytovala stovky trilionů možností. Přesto byla prolomena díky kombinaci:

  • systematické práce kryptografů, zejména Alana Turinga a jeho týmu v Bletchley Parku,
  • chybám v používání šifrovacích klíčů,
  • využití známého textu a statistik při prolomení denních klíčů.

Příklad šifrování textu HELLO

V Enigmě nelze jednoduše demonstrovat kompletní proces ručně, protože výsledné písmeno závisí na aktuální pozici rotorů a plugboardu. Pro ilustraci lze uvést simulovaný výsledek při jednom konkrétním nastavení:

Text: HELLO
Zašifrovaný text: MFNCZ

Každé písmeno se mění podle složitého elektrického průchodu přes rotory a plugboard, a při každém stisku klávesy se konfigurace rotorů posune, takže další písmeno má úplně jinou substituci.

Implementace Enigma v C#

Zjednodušená

Implementace plné Enigmy je složitá, ale zjednodušenou verzi lze demonstrovat jedním rotorem a substituční tabulkou:

using System;
using System.Collections.Generic;

class SimpleEnigma
{
    private string rotor = "EKMFLGDQVZNTOWYHXUSPAIBRCJ"; // zjednodušený rotor
    private int position = 0;

    private char EncryptChar(char c)
    {
        if (!char.IsLetter(c)) return c;
        int index = (c - 'A' + position) % 26;
        char encrypted = rotor[index];
        position = (position + 1) % 26;
        return encrypted;
    }

    public string Encrypt(string input)
    {
        input = input.ToUpper();
        var result = "";
        foreach (var c in input)
            result += EncryptChar(c);
        return result;
    }
}

class Program
{
    static void Main()
    {
        var enigma = new SimpleEnigma();
        string plaintext = "HELLO";
        string encrypted = enigma.Encrypt(plaintext);
        Console.WriteLine($"Původní text: {plaintext}");
        Console.WriteLine($"Zašifrovaný text: {encrypted}");
    }
}

Plná

plná implementace Enigmy je o něco komplexnější, protože musí obsahovat:

  • více rotorů, každý s vlastním posunem a zapojením,
  • reflektor, který odráží signál zpět,
  • plugboard (steckerbrett) pro párování písmen,
  • rotaci rotorů (tzv. stepping), včetně „double-step“ mechanismu.

Níže je plná implementace Enigma v C#.

using System;
using System.Collections.Generic;
using System.Linq;

namespace EnigmaMachine
{
    class Rotor
    {
        public string Wiring { get; }
        public char Notch { get; }
        public int Position { get; set; }

        public Rotor(string wiring, char notch, char initialPosition)
        {
            Wiring = wiring;
            Notch = notch;
            Position = initialPosition - 'A';
        }

        public char Forward(char c)
        {
            int idx = (c - 'A' + Position) % 26;
            return Wiring[idx];
        }

        public char Backward(char c)
        {
            int idx = Wiring.IndexOf(c);
            int result = (idx - Position + 26) % 26;
            return (char)(result + 'A');
        }

        public bool AtNotch() => (Position + 'A') == Notch;

        public void Step() => Position = (Position + 1) % 26;
    }

    class Enigma
    {
        private Rotor[] rotors;
        private Dictionary<char, char> plugboard;
        private string reflector;

        public Enigma(Rotor[] rotors, string reflector, Dictionary<char, char> plugboard = null)
        {
            this.rotors = rotors;
            this.reflector = reflector;
            this.plugboard = plugboard ?? new Dictionary<char, char>();
        }

        private char SwapPlugboard(char c)
        {
            return plugboard.ContainsKey(c) ? plugboard[c] : c;
        }

        private void StepRotors()
        {
            if (rotors[1].AtNotch())
            {
                rotors[0].Step();
                rotors[1].Step();
            }
            else if (rotors[2].AtNotch())
            {
                rotors[1].Step();
            }
            rotors[2].Step();
        }

        public string Encrypt(string text)
        {
            text = text.ToUpper().Where(char.IsLetter).Aggregate("", (s, c) => s + c);
            var result = "";

            foreach (var c in text)
            {
                StepRotors();

                char current = SwapPlugboard(c);

                for (int i = rotors.Length - 1; i >= 0; i--)
                    current = rotors[i].Forward(current);

                current = reflector[current - 'A'];

                for (int i = 0; i < rotors.Length; i++)
                    current = rotors[i].Backward(current);

                current = SwapPlugboard(current);

                result += current;
            }

            return result;
        }
    }

    class Program
    {
        static void Main()
        {
            var rotorI = new Rotor("EKMFLGDQVZNTOWYHXUSPAIBRCJ", 'Q', 'A');
            var rotorII = new Rotor("AJDKSIRUXBLHWTMCQGZNPYFVOE", 'E', 'A');
            var rotorIII = new Rotor("BDFHJLCPRTXVZNYEIWGAKMUSQO", 'V', 'A');

            string reflectorB = "YRUHQSLDPXNGOKMIEBFZCWVJAT";

            var plugboard = new Dictionary<char, char> {
                {'A','B'}, {'B','A'}, {'C','D'}, {'D','C'}
            };

            var enigma = new Enigma(new[] { rotorI, rotorII, rotorIII }, reflectorB, plugboard);

            string plaintext = "HELLO";
            string encrypted = enigma.Encrypt(plaintext);

            Console.WriteLine($"Původní text: {plaintext}");
            Console.WriteLine($"Zašifrovaný text: {encrypted}");
            
            var decrypted = enigma.Encrypt(encrypted);
            Console.WriteLine($"Dešifrovaný text: {decrypted}");
        }
    }
}
Vysvětlení
  1. Rotory – tři rotory s nastavitelnou počáteční pozicí a „notch“ pro posun dalších rotorů.
  2. Reflektor – jednoduchý substituční řetězec, který odráží písmena zpět.
  3. Plugboard – umožňuje předem definované párování písmen.
  4. Kroky rotorů – implementuje mechaniku Enigmy včetně double-stepping efektu.
  5. Šifrování a dešifrování – stejná metoda, protože Enigma je symetrická.

Závěr

Enigma ukazuje, jak kombinace mechanických a elektrických prvků dokáže vytvořit extrémně složité šifrování. Přestože byla v době druhé světové války považována za téměř neprůstřelnou, její prolomení ukázalo, že i velmi složité šifry lze překonat kombinací matematiky, statistiky a znalostí systému. Enigma je dnes ikonou kryptografie a důležitým historickým příkladem evoluce šifrovacích metod.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *