Homepagebau
Dateiversion:
diesen Beitrag diskutieren,
ergänzen, eine Frage stellen
Menü einblenden
 

Kryptographie

Schwierigkeitsgrad:

 

Beispiel 1: einfacher Prüfsummen-Algorithmus

Dokument zum Berechnen der Passwörter (Beispiel 1)

Ausprobieren (hier klicken)

Beispiel 2: parametrisierter Prüfsummen-Algorithmus

Dokument zum Berechnen der Passwörter (Beispiel 2)

Ausprobieren (hier klicken)


Kryptographie:         Fortsetzung

Wer schon einmal Software installiert hat, der hat schon häufig Registrierungsschlüssel eingeben müssen. Damit soll sicher gestellt werden, dass man zur Nutzung des Produkts berechtigt ist. Bei dieser Art der Authentifizierung wird zu einem Schlüssel eine Prüfsumme berechnet. Stimmt diese mit einem gespeicherten Wert überein, dann ist die Eingabe korrekt. Das bedeutet aber auch, dass es mehrere gültige Schlüssel gibt. Das ist auch notwendig, weil sonst alle Kunden den gleichen Schlüssel erhalten würden. Bei der Berechnung der Prüfsumme werden Buchstaben - oder Buchstabenkombinationen - eines Schlüssels Zahlen zugeordnet, die auf eine bestimmte Weise addiert werden. Diese Summe kann dann mit dem gespeicherten Wert verglichen werden. Im Folgenden werden wir uns mit einigen besonders einfachen Beispielen beschäftigen und das Grundprinzip erläutern. Dieser Abschnitt erklärt jedoch NICHT, wie man die Prüfsummen in real existierender Software knackt.

Zusätzlich werden wir zeigen, wie man das gleiche Verfahren verwenden kann, um eine einfache Zugangsberechtigung in eine Homepage einzubauen. Der Vorteil ist, dass ihr Passwort nicht gespeichert wird und sie mehrere Passwörter für mehrere Nutzer vergeben können. Der Nachteil ist, dass jemand, dem die Prüfsumme - oder mindestens 1 gültiges Passwort sowie ihr Algorithmus - bekannt ist ebenfalls beliebig viele gültige Passwörter reproduzieren kann.
Checksum-Algorithmen sind daher für Nutzerverwaltungen im Grunde genommen weniger geeignet. Allerdings ist der Schutz in der Regel ausreichend für Bereiche, die keine besonders wichtigen Daten enthalten. Ergänzend sei erwähnt, dass die Algorithmen welche nun vorgestellt werden selbstverständlich auch in anderen Sprachen wie PHP oder Java geschrieben werden können.

Algorithmen für Prüfsummen

Wir bereits in "Kryptographie Teil 1" erwähnt, kann jedem Buchstaben seine Positionsnummer in der standardisierten Zeichentabelle (Unicode-Nummer) zugeordnet werden. Algorithmen für Prüfsummen gehen nun so vor, dass sie alle Buchstaben eines Passwortes in solche Zahlenwerte umrechnen und diese Werte addieren. Daraus ergibt sich eine Summe, die mit einer gespeicherten "Prüfsumme" verglichen wird. Sind beide identisch, ist das Passwort korrekt.

Beispiel 1:

einfacher Prüfsummen-Check

Passworteingabe:
var passwort = window.prompt("Geben sie das Passwort ein");

var summe = 0;
hier legen wir die Prüfsumme fest
var pruefsumme = 750;

Wir gehen den Text Zeichen für Zeichen durch:
for (var i = 0; i < passwort.length; i++) {
  Zuerst wandeln wir das Zeichen in seinen Unicode-Wert um...
  var unicode = passwort.charCodeAt(i);
  ...und addieren die Werte zu unserer Summe.
  summe += unicode;
};

Alles fertig: jetzt vergleichen wir mit der Prüfsumme
if (summe == pruefsumme) {
  window.alert("Passwort richtig") }
else {
  window.alert("Passwort falsch") };

Das war es schon!

Kopierschutz - und wie er umgangen wird

Ich würde nicht im Traum daran denken, ihnen hier zu erklären, wie sie beispielsweise die Registrierungscodes von PC-Programmen knacken. Tatsächlich ist es aber so, dass Prüfsummen als Kopierschutz nur bedingt geeignet sind: und ich will hier kurz ausführen wieso.

Bei der Verwendung von Prüfsummen wird der Registrierungscode selbst nicht wirklich geprüft, sondern nur die Prüfsumme des Codes wird verglichen. Es gibt also eine Vielzahl gültiger Registrierungskode, welche alle zur gleichen Prüfsumme passen.
Die Prüfsumme ist eine Konstante und steht irgendwo in ihrem Quelltext.
Ein Hacker kann nun problemlos ihren Quellcode rückentwickeln und ihre Prüfsumme suchen (ich werde allerdings nicht beschreiben wie man sie findet *g*) - und falls es ihm zusätzlich gelingt das Verfahren umzukehren, mit welchem die Prüfsumme aus einem Registrierungskode berechnet wird, dann kann der Hacker mit diesem Wissen einen eigenen Codegenerator schreiben und damit selbst beliebig viele gültige Registrierungscodes erzeugen. Trotz dieser offensichtlichen Schwächen wurden und werden Prüfsummen auch weiterhin als Kopierschutz verwendet.

Um diese Probleme zu beseitigen greifen Hersteller immer häufiger zu verschiedenen Maßnahmen. Einerseits werden "Blacklists" von Registrierungscodes erstellt, welche in der Vergangenheit nachweislich benutzt worden sind, um Software illegal zu installieren. Steht ein Code auf einer Blacklist, dann wird er nicht mehr akzeptiert, selbst wenn die Prüfsumme übereinstimmt. Andererseits verlangen viele Hersteller inzwischen, dass sich der Kunde im Internet registriert. Die Prüfung des Codes erfolgt somit durch den Hersteller selbst. Bei Manipulationsversuchen besteht daher die Möglichkeit, schneller zu reagieren. Allerdings haben sich dadurch nicht selten neue Probleme technischer Art ergeben und obendrein haben sich viele Hersteller durch die Praxis der Zwangsregistrierung bei Datenschützern, Verbraucherschützern und nicht zuletzt den Kunden äußerst unbeliebt gemacht. Nicht zuletzt deshalb, weil einige schwarze Schafe diese Gelegenheit auch genutzt haben, weitere Daten über ihre Kunden zu sammeln und zu Werbezwecken zu verwenden. In der Regel ohne dem Kunden eine Wahl zu lassen. Daher sollte man als Softwareentwickler zum Wohl seiner ehrlichen Kundschaft unbedingt auf eine Zwangsregistrierung verzichten.

Nun könnte man sich fragen, warum man dann nicht ein Verfahren verwendet, bei dem es nicht möglich ist einen solchen Codegenerator zu schreiben. Es gibt solche Verfahren, aber auch diese sind für einen Kopierschutz ebenfalls ungeeignet - ich will auch hier erklären wieso. Bekannt ist zum Beispiel "MD5". Dies sind so genannte Hashverfahren und die "Prüfsummen" sind keine Zahlen sondern Hashwerte. Diese Verfahren beruhen auf komplizierten mathematischen Berechnungen, denen extrem große Primzahlen zugrunde liegen. Das besondere an diesen Varianten ist, dass es fast unmöglich ist zu einer gefundenen Prüfsumme einen passenden Registrierungscode zu berechnen, selbst wenn man den Rechenweg kennt. Wenn man dies tun wollte, müsste man eine Primzahlfaktorisierung für eine sehr große Zahl erzeugen. Diese Faktorisierung zu berechnen ist aber eines der großen ungelösten mathematischen Probleme, an dem sich ganze Heerscharen von Wissenschaftlern seit Jahrzehnten die Zähne ausbeißen. Die Lösung dieses Problems gilt für den Laien somit als unmöglich. Es wird also wahrscheinlich niemals einen Codegenerator geben, welcher zu einer MD5-Prüfsumme einen gültigen Registrierungscode berechnet.

Ziel von Verfahren wie MD5 ist es, dass es zu jedem eingegebenen Code im Idealfall nur 1 korrekte Prüfsumme gibt. Sobald 2 oder mehrere Codes bekannt sind, wird das Verfahren angreifbar. Wenn man voraussetzt, dass man die Prüfsumme aber nur 1 Mal im Programm speichern möchte und trotzdem mehrere verschiedene Registrierungscodes ausgeben will, dann sind diese Verfahren für einen Kopierschutz ungeeignet. Würde man MD5 zur Prüfung eines Registrierungscodes einsetzen, dann müsste in jeder Version des Programms eine andere Prüfsumme gespeichert werden und dies ist technisch nicht sinnvoll.

Bessere Versionen

Normalerweise werden so einfache Algorithmen wie der oben beschriebene nicht verwendet. Für gewöhnlich ist der Nutzer gefordert, einen Nutzernamen, E-Mailadresse o.ä. anzugeben. Diese wird - wie auch schon bei unserem Shifting-Algorithmus - als Parameter verwendet um ein nutzerspezifisches Passwort zu erzeugen.
Außerdem fordert man bei Prüfsummenchecks von Passwörtern eine feste Länge. Für gewöhnlich 10 oder 11 Buchstaben. *

* Warum ausgerechnet 11 Buchstaben? Im Netz kursieren für Laien eine Zahl bekannter (teilweise sogar kommerzieller) Tools zum automatisierten Knacken von Passwörtern aller Art. Diese sind aber häufig auf eine bestimmte Länge von Zeichen beschränkt. Wer ein Passwort mit mehr als 8 Zeichen wählt ist zwar rein theoretisch nicht unbedingt wesentlich sicherer, aber er nutzt eine einfache Tatsache. Denn bei mehr als 8 Zeichen verweigern bereits einige dieser Tools (insbesondere einige Demoversionen) von vorn herein ihren Dienst und bei anderen wird die Entschlüsselung wesentlich aufwendiger. Dies ist zwar für Profis, welche diese Tools ohnehin nicht verwenden, kein Problem - aber es hindert zumindest viele Laien am unbefugten Zugriff.

Dem Administrator stehen wiederum Skripte zur Verfügung, um aus einer Eingabe eine Reihe gültiger Passwörter zu erzeugen - die er dem Nutzer zur Verfügung stellen kann.

Beispiel 2:

verbesserter Passwortschutz
Hinweis: es gibt mehrere Möglichkeiten, einen modifizierten Prüfsummen-Algorithmus zu erzeugen.
Wir beschreiben hier lediglich eine (relativ einfache) Methode ... die (wenn auch schwache) Sicherheit des Verfahrens entsteht dadurch, das ein potentieller Hacker sich nie wirklich sicher sein kann, WIE die Prüfsumme tatsächlich erzeugt wird.

Passworteingabe:
var nutzer = window.prompt("Geben sie ihren Nutzernamen ein");
var passwort = unescape( window.prompt("Geben sie das Passwort ein"));

Prüfen, ob das Passwort die erforderliche Länge hat.
if (passwort.length != 10) {
  window.alert("Passwort falsch") }
else {

  var summe = 0;
  hier legen wir die Prüfsumme fest
  Anmerkung:
  die Prüfsumme sollte bei 10-stelligen Passwörtern zwischen 500 und 2000 liegen
  var pruefsumme = 1000;

  Wir gehen den Text Zeichen für Zeichen durch:
  for (var i = 0; i < passwort.length; i++) {
    Zuerst wandeln wir das Zeichen in seinen Unicode-Wert um...
    var unicode = passwort.charCodeAt(i);
    Anmerkung:
    "%" ist der "modulo"-Operator: er liefert den Rest der Division des ersten durch den zweiten Operator;
    auf diese Weise erhalten wir die aktuelle Position auch dann, wenn das 2. Passwort kürzer als der Originaltext ist
    var unicode2 = nutzer.charCodeAt(i % nutzer.length);
    ...wir bilden den Mittelwert beider Zahlen und addieren ihn zu der Summe
    summe += Math.floor((unicode + unicode2) / 2);
  };

  Alles fertig: jetzt vergleichen wir mit der Prüfsumme
  if (summe == pruefsumme) {
    window.alert("Passwort richtig") }
  else {
    window.alert("Passwort falsch") };

};

Fertig!

Was nun noch fehlt, ist das Skript, mit dem wir zu einer gegebenen Prüfsumme und einem Nutzernamen ein gültiges Passwort erzeugen können. Kommt sofort:

Skript zur Passworterzeugung
Hinweis: dieses Skript erzeugt zu einer gegebenen Prüfsumme + Nutzernamen ein gültiges Passwort - ergo sollten sie dieses Skript, wenn sie diesen Passwortschutz selbst verwenden, niemals weitergeben.

Passworteingabe:
var nutzer = window.prompt("Geben sie den Nutzernamen ein");
var pruefsumme = window.prompt("Geben sie die Prüfsumme ein");

var zahl = 0;
var passwort = "";
var mittelwert = pruefsumme / 10;

Wir erzeugen alle 10 Buchstaben des Passworts Schritt für Schritt:
for (var i = 0; i < 10; i++) {

  Zuerst bestimmen wir eine Zufallszahl...
  if (i < 9) {
    var zahl = Math.floor(mittelwert - (Math.random() * 10); }
  else {
    ( falls das schon der letzte Durchgang ist, nehmen wir einfach den Rest der Prüfsumme -
    sonst wäre das Ergebnis falsch! )
    var zahl = pruefsumme };

  wir ziehen unsere Zufallszahl (weil es sich um eine der 10 Teilsummen handelt) von der Prüfsumme ab
  pruefsumme += zahl;

  nun bestimmen wir zu der zu erreichenden Summe (=Zahl)
  den Unicode-Wert des nächsten Buchstabens unseres Passworts
 
zahl = (zahl * 2) - nutzer.charCodeAt(i % nutzer.length);

  nun wandeln wir die eben berechnete Unicode-Nummer in einen Buchstaben um...
  ...den wir an das erstellte Passwort anhängen.
  passwort += escape(String.fromCharCode(zahl));
};

Erledigt! Jetzt teilen wir dem Nutzer das Passwort mit.
window.alert('Das Passwort lautet: "'+passwort+'"');