Nico: Wie funktioniert das eigentlich mit der Crypt Verschlüsselung?

Hallo!

Auf der Seite von SelfHTML zu .htaccess (http://de.selfhtml.org/servercgi/server/htaccess.htm) wird ja die Verschlüsselung mit der Cryptmethode erwähnt und auch noch ein Formular dazu angeboten.
Wenn man in das Formular dann mal zweimal die gleiche Zeichenkette eingibt und abschickt, kommt beide Male was verschiedenes raus.
Wie ist denn das dann möglich, dass der Server erkennt, dass das das richtige Passwort ist? Das kann man doch ohne einen Schlüssel auch nicht entschlüsseln, oder? Und wenn da beim Verschlüsseln immer was anderes rauskommt, hat der doch nichts zum Vergleichen.
Weiß jemand, wie der das macht?

Nico

  1. Sup!

    RTFA!

    (Lies im Archiv!)

    Gruesse,

    Bio

    -- Keep your friends close, but your enemies closer!
  2. Hallo Nico,

    Wenn man in das Formular dann mal zweimal die gleiche Zeichenkette eingibt und abschickt, kommt beide Male was verschiedenes raus.

    Ja, weil immer ein zweistelliger Zufallscode erzeugt wird, der für das Hashen verwendet wird. Wenn Du also 'hallo' als Zeichenkette wählst und die ins Formular eingibst, wird ein zweistelliger Zufallscode erzeugt; beim ersten Mal bspw. S3, beim zweiten Mal z.B. nN. Dieser Code wird nun als die ersten beiden Buchstaben des gehashten Passworts abgespeichert, d.h. das erste gehashte Passwort lautet S393N4O5IZT5k, das zweite nNdn0yE8maujQ (achte auf die Anfangsbuchstaben; beide Mal wurde 'hallo' gehasht).

    Wenn nun ein Benutzer sein Passwort an den Server schickt um sich anzumelden, dann kennt der Server das Passwort, das der Benutzer eingegeben hat, im Klartext. Der Server liest nun das gehashte Passwort des Benutzers aus, extrahiert davon die ersten zwei Zeichen. Diese zwei Zeichen nimmt er nun _anstelle_ von Zufallszeichen und hasht diese zusammen mit dem Passwort. Das Ergebnis vergleicht er dann.

    Anschaulich:

    Festlegen des Passworts:

              +-------+
              | hallo |
              +-------+
                  |
                  v
        +----------------------+          +-----------------------------+
        | crypt()-Hashfunktion |<---------| 2 Zeichen Zufallsdaten 'S3' |
        +----------------------+          +-----------------------------+
                  |
                  |
                  v
         +-----------------------------------+
         | S393N4O5IZT5k (gehashtes Passwort |
         +-----------------------------------+

    Vergleichen des Passworts:

         +-------+          +-----------------------------------+
         | hallo |          | S393N4O5IZT5k (gehashtes Passwort |
         +-------+          +-----------------------------------+
             |                \/                   |
             |                /                    |
             |     -----------                     |
             |    /                                |
             |    |(die ersten 2 Zeichen)          |
             v    v                                |
       +----------------------+                    v
       | crypt()-Hashfunktion |                 +------------------+
       +----------------------+             --->| Stimmen überein? |
             |                             /    +------------------+
             v                             |           |
         +-----------------------------------+         v
         | S393N4O5IZT5k (gehashtes Passwort |      +---------------------+
         +-----------------------------------+      | Ja, Passwort stimmt |
                                                    +---------------------+

    Vergleichen eines falschen Passworts:

         +-------+          +-----------------------------------+
         | biene |          | S393N4O5IZT5k (gehashtes Passwort |
         +-------+          +-----------------------------------+
             |                \/                   |
             |                /                    |
             |     -----------                     |
             |    /                                |
             |    |(die ersten 2 Zeichen)          |
             v    v                                |
       +----------------------+                    v
       | crypt()-Hashfunktion |                 +------------------+
       +----------------------+             --->| Stimmen überein? |
             |                             /    +------------------+
             v                             |           |
         +-----------------------------------+         v
         | S333t7QDD2R.k (gehashtes Passwort |      +-----------------------+
         +-----------------------------------+      | Nein, Passwort falsch |
                                                    +-----------------------+

    Noch etwas: crypt() ist kein Verschlüsselungsalgorithmus, sondern eine Hashfunktion. Eine Hashfunktion zeichnet sich dadurch aus, dass sie dazu gedacht ist, eben *nicht* rückgängig gemacht werden zu können. Die einzige Möglichkeit, das Hash einer idealen Funktion zu "entschlüsseln", ist das Durchprobieren aller Möglichkeiten.

    crypt() gilt auf Grund von einigen Limitationen (max. 8 Zeichen, der Rest wird abgeschnitten) nicht mehr als wirklich sicher. md5() wurde lange Zeit als sicherer propagiert, da es unendlich viele Zeichen akzeptiert hat und allgemein als sicher angesehen wurde. Inzwischen sind jedoch schon Angriffsmöglichkeiten auf md5 bekannt, der Algorithmus ist daher nicht mehr als sicher einzustufen. Eine Alternative ist SHA1, der jedoch inzwischen auch nicht mehr als 100% sicher gilt, im Moment jedoch noch als hinreichend sicher betrachtet wird. Als wirklich sicher gelten im Moment nur SHA2-basierte Algorithmen sowie Blowfish. Allerdings sollte man hier die Verhältnismäßigkeit betrachten: der Angreifer muss erst einmal Zugang zum Hash erlangen, um überhaupt was durchprobieren zu können - und da das Hash in einer .htpasswd-Datei gespeichert wird und diese meistens nicht öffentlich zugänglich ist, dürfte MD5 meiner Ansicht nach völlig dafür ausreichen (crypt() nur wegen der 8-Zeichen-Begrenzung nicht).

    Du kannst in .htpasswd-Dateien auch MD5 oder SHA1 einsetzen, allerdings verwendet der Apache-Server eine leicht abgewandelte Version der beiden Algorithmen; MD5 und SHA1 bauen im Normalfall nämlich keine Zufallszeichen mit ein. Um einen MD5- oder SHA1-Hash zu erzeugen, den der Apache auch schluckt, hilft Dir das mit dem Apache (auch unter Windows mitgelieferte) Tool »htpasswd« weiter. Das kann unter Windows zwar kein crypt(), allerdings kann es durchaus md5() und sha1(), die unter Unix mit dem Apache genauso funktionieren.

    htpasswd -m dateiname benutzername
         würde ein md5-hash des noch einzugebenden Passworts erzeugen und
         dieses zusammen mit »benutzername« in »dateiname« schreiben.

    htpasswd -s dateiname benutzername
         würde ein sha1-hash des noch einzugebenden Passworts erzeugen und
         dieses zusammen mit »benutzername« in »dateiname« schreiben.

    Die Aufrufsyntax ist unter Windows wie auch unter Unix die gleiche; in beiden Fällen muss htpasswd im PATH vorhanden sein (unter Windows im Zweifel ins Apache\bin-Verzeichnis wechseln).

    Viele Grüße,
    Christian

    1. [Nominiert für das Hilfreicheste und schönste Post 2005] =)

      ciao

      --
      <NetPanther> Na, die Stadt ist Developia, die Hauptstadt von Developien!
      <NetPanther> Developien ist übrigens ein Entwicklungsland!

      <acid`awy> bossi was haste fuern abschluss ?
      <[DEF]Bossland> tdsl

      http://german-bash.org/action/top/n/50

      sh:) fo:| ch:{ rl:( br:& n4:~ ie:| mo:? va:{ de:< zu:| fl:) ss:| ls:< js:|

      1. Hallo Sebastian,

        [Nominiert für das Hilfreicheste und schönste Post 2005] =)

        Die erste Aussage stimmt so (noch?) nicht, das Posting, in dem die
        Veröffentlichung von SelfHTML 8.1 bekannt gegeben wurde war
        mindestens doppelt so hilfreich ;-)

        Gruß
        Alexander Brock

        http://againsttcpa.com

        -- SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:? ss:| de:> js:( ch:| sh:( mo:} zu:}
    2. Vielen Dank!