Home » Tipps & Tricks » Algorithmen » Verschlüsselungen » Vigenère

Vigenère

Die Vigenère-Verschlüsselung wurde 1553 von Giovan Battista Bellaso erstmals beschrieben. Später wurde er Blaise de Vigenère zugesprochen, dessen Namen er heute noch trägt. Lange Zeit galt dieser Algorithmus als sicher. Seit Mitte des 19. Jahrhunderts gilt er allerdings als geknackt und sollte deshalb nur noch zu Lehr- und Demonstrationszwecken genutzt werden.

implementation

uses
  Math;

function EncryptVigenere(AText: string; AKey: string): string;
var
  i: integer;             // aktuelle Position im Text
  counter: integer;       // aktuelle Position im Schlüsselwort
  curKeyLetter: integer;  // der momentane Schlüssel-Buchstabe aus dem Schlüsselwort
  curLetter: integer;     // der momentan zu verschlüsselnde Buchstabe
begin
  SetLength(Result, Length(AText));
  counter := 0;
  
  // alles in Großbuchstaben umwandeln
  // Vigenere unterscheidet nicht zwischen Groß- und Kleinbuchstaben
  AText := UpperCase(AText);
  AKey := UpperCase(AKey);
  
  for i := 1 to Length(AKey) do
  begin
    if not (AKey[i] in ['A'..'Z']) then
      raise EInvalidArgument.Create('Der Schlüssel darf nur Buchstaben enthalten');
  end;
  
  for i := 1 to Length(AText) do
  begin
    if AText[i] in ['A'..'Z'] then  // nur Buchstaben verschlüsseln
    begin
      curKeyLetter := Ord(AKey[1 + (counter mod Length(AKey))]) - ord('A');
      curLetter := Ord(AText[i]) - Ord('A');
      
      // verschlüsseln
      Result[i] := Chr(Ord('A') + ((curLetter + curKeyLetter) mod 26));
      
      inc(counter);
    end
    else
    begin
      Result[i] := AText[i]; // nicht verschlüsseln, wenn kein Buchstabe
    end;
  end;
end;

function DecryptVigenere(AText: string; AKey: string): string;
var
  i: integer;             // aktuelle Position im Text
  counter: integer;       // aktuelle Position im Schlüsselwort
  curKeyLetter: integer;  // der momentane Schlüssel-Buchstabe aus dem Schlüsselwort
  curLetter: integer;     // der momentan zu entschlüsselnde Buchstabe
begin
  SetLength(Result, Length(AText));
  counter := 0;

  // alles in Großbuchstaben umwandeln
  // Vigenere unterscheidet nicht zwischen Groß- und Kleinbuchstaben
  AText := UpperCase(AText);
  AKey := UpperCase(AKey);
  
  for i := 1 to Length(AKey) do
  begin
    if not (AKey[i] in ['A'..'Z']) then
      raise EInvalidArgument.Create('Der Schlüssel darf nur Buchstaben enthalten.');
  end;

  for i := 1 to Length(AText) do
  begin
    if AText[i] in ['A'..'Z'] then  // nur Buchstaben entschlüsseln
    begin
      curKeyLetter := Ord(AKey[1 + (counter mod Length(AKey))]) - ord('A');
      curLetter := Ord(AText[i]) - Ord('A');

      // entschlüsseln
      Result[i] := Chr(Ord('A') + ((26 + curLetter - curKeyLetter) mod 26));
      
      inc(counter);
    end
    else
    begin
      Result[i] := AText[i];  // nur Buchstaben sind Verschlüsselt
    end;
  end;
end;

Aufruf:

procedure TForm1.VerschluesselnButtonClick(Sender: TObject);
begin
  Memo1.Text := EncryptVigenere(Memo1.Text, 'MeinGeheimerSchluessel');
end;

procedure TForm1.EntschluesselnButtonClick(Sender: TObject);
begin
  Memo1.Text := DecryptVigenere(Memo1.Text, 'MeinGeheimerSchluessel');
end;

Das Prinzip der Vigenère-Chiffre ist recht einfach: Die einzelnen Buchstaben des Passwortes geben an, um wie viele Stellen das Alphabet verschoben werden soll. Dabei gilt das erste Zeichen des Passworts für das erste Zeichen des zu verschlüsselnden Textes, das zweite für das zweite, und so weiter. Ist das Passwort kürzer als der zu verschlüsselnde Text, wird das Passwort wiederholt verwendet. Hat der Schlüssel die Länge 1, so ist das Ergebnis das gleiche, wie bei der Caesar-Verschlüsselung – abgesehen davon, dass für Caesar ein um eins niedrigerer Schlüssel genommen werden muss, d.h. Vigenère mit dem Schlüssel ‚D‘, entspricht Caesar mit dem Schlüssel ‚C‘.

Für weitere Informationen zur Vigenère-Verschlüsselung siehe den Wikipedia-Artikel Polyalphabetische Substitution.