orm@doc-tcpip.org

Erstellt: Februar 2003 - Letzte Modifikation: Februar 2005

[ Main | Local ]


Verschlüsselung von Passwörtern unter Unix

crypt(), DES, /etc/passwd usw.

Wie ist es unter Unix mit den Passwörtern?

Aus der Sicht des Users

Als User erlebt man es meistens in dieser Art: Man muß einen Antrag stellen, und wird dann von einem Systemadministrator eingerichtet, und erhält ein Passwort genannt (meist der User-Name). In diesem Moment kann man gleich abschätzen, welchen Stellenwert Sicherheit und Sorgfalt haben - ein guter Administrator wird dem User einschärfen, sein Passwort gleich zu ändern und auch allgemein über gute und schlechte Passwörter reden. Wenn man sich dann zum erstenmal einloggt, dann wird man zusätzlich noch zur Änderung des Passwortes gezwungen und das Passwort wird auf gewissen Mindest-Regeln geprüft. Auf einem nicht gut administrierten System kann man sein Passwort lassen wie man will, oder man muß es alle 4 Wochen ändern und dabei mindesten 100 schwachsinnige Regeln beachten.

Gute und schlechte Passwörter

Schlecht ist alles, was man in einem Wörterbuch finden könnte und alle Daten, die mit der eigenen Person verbunden werden könnten. Das sind Geburtstage, Namen der Freundinnen, Wörter aus dem Hobby Bereich, Namen von Kindern und Pferden etc. etc.

Auch der Begriff Wörterbuch ist hier sehr weit zu fassen: Ein Wörterbuch ist jede Menge an Wörtern und Bruchstücken, die sich elektronisch erzeugen lassen, indem man z.B. einfach lange Texte, E-Mail usw. auflistet.

Ein gutes Passwort ist schwer zu erraten und leicht zu Merken. Man nimmt sich am Besten einen Satz, der für einen eine besondere Bedeutung hat - und leitet daraus, angelehnt an den Satz und mit eine Zahl versehen, das Passwort ab.

Ein paar Beispiele:
Macht kaputt, was euch kaputt macht
==> mK03wekM
Monthy Python ist auch gut:
And now for something completely different
==> aNf3Cd
Wobei der Satz in persönlicher Betonung gesprochen wird und something in three-thing verballhornt wurde...
Sehr gut sind auch bedingt sinnvolle Sätze:
Alle acht Schweine waren voll schwanger, falsch
==> A8sw0Sf
(Null ist das Gegenteil von voll.... ).

Wie knackt man Passwörter?

Gegen Unix-Passwörter ist eigentlich nur eine dictionary attack erfolgversprechend. Der Algorithmus ist so beschaffen, daß man vom Verschlüsselungs-Produkt nicht mehr auf das Klartext-Passwort schließen kann. Daher nimmt man das oben erwähnte Wörterbuch her und läßt alle Wörte durch den Algorithmus laufen. Dadurch erhält man ein Wörterbuch der Produkte des Algorithmus, die kann man speichern und direkt mit dem String in der /etc/shadow oder /etc/security/user vergleichen.

Wieviele Passwörter sind eigentlich möglich?

Wir gehen von 101 Zeichen aus, also 39 Interpunktionen, 10 Zahlen, 26 kleinen und 26 großen Buchstaben (man sollte bewußt die Länderspezifika ausschließen - schließlich möchte man auch auf einer englischen Tastatur ein Log-In hinkriegen).

Damit wird die Summe aller 7- und 8-stelligen Passwörter (frei gewählt):
101^8+101^7 = 10935780591491502
Ist die Passwort-Länge egal, dann kommt man auf
Summe über 101^n, n= 1 - 8, also 101^9 = 1093685272684360900

Da es wehr wichtig ist, daß die Passwörter nicht zu erraten sind, sollte man lange Passwörter erzwingen (mindestens 6 Zeichen). Der Verlust an Möglichkeiten liegt bei 10^2, jedoch macht man Bösewichtern das Leben sehr schwer.

Allerdings darf man nicht vergessen, daß man mit jeder Einschränkung die Zahl der möglichen Passwörter weiter einschränkt! Solche Einschränkungen lassen sich in Erfahrung bringen, und ein 6-Stelliges Passwort mit mindestens einer Interpunktion und zwei Zahlen ist mit heutigen Rechnern leicht zu finden.

Erzwingt man z.B. ein Passwort mit mindestens 7 Stellen und mindestens 3 alphanumerischen Zeichen, so beschränkt man den zu durchsuchenden Bereich um 52^3/101^3.

Am Besten sind ganze Passphrases, also ein ganzer Satz, über den dann eine Checksumme bzw. Signatur gemacht wird.

Bringt Passwort-Faschismus wirklich etwas?

Nein, natürlich nicht. Vernünftig ist eine Mindestlänge und vielleicht mindestens eine Zahl oder Sonderzeichen. Muß man ganz sicher sein, dann sollte man regelmäßige Änderung in sinnvollen Abständen erzwingen - natürlich nur mit Maßnahmen gegen Passwort-Wiederverwendung...

Das allerwichtigste ist aber, daß man den Usern ins Gewissen redet und oft über gute Passwörter belehrt.

Wie wird das technisch umgesetzt?

Standard ist heute, daß User die verschlüsselten Strings nicht zu sehen bekommen. Diese werden, je nach Unix-Dialekt, in Dateien wie /etc/shadow, /etc/security/passwd etc. abgelegt und sind nur Root zugänglich.

Zunehmend sind auch die Systeme, wo ein MD5-Hash oder sonst eine starke Verschlüsselungs-Technik eingesetzt werden. Das erkennt man an den langen Strings in den einschlägigen Files (hier /etc/shadow von einem Linux, Schreib- und Lese-Rechte nur für Root):

 
orm:$1$5A8cRJgX$KGmoDLTIMrTKvelttPxH4/:11730:0:99999:7:::
cristina:$1$KTo2wMVv$hDoXCiz1yOzk7HqN7tnuL0:11730:0:99999:7:::

Die klassische Form basiert jedoch auf DES und der crypt()-Funktion (die ist ein Teil der libca, einer System-Library).

DES ist ein Block-Cipher. Der Klartext wird in 64-Bit Blöcke zerschnitten, Permutiert und dann in verschiedenen Runden mit einem zyklisch permutierten 56-Bit Schlüssel verrechnet (Binär, XOR). Die Zyklen werden mehrmals durchlaufen (16, 20 oder 25 mal). Dazwischen wird das Ergebniss noch mit fest vorgegeben Tabellen-Werten (S-Boxen) verschränkt. Unter Kenntnis des Passwortes kann man aus dem verschlüsselten Text dann wieder den Klartext erhalten.

Im Fall des Unix-Logins wird ein Feld von Nullen mit dem User-Passwort als Schlüssel durch den Algorithmus geführt. Um die Anzahl der möglichen Passwörter noch weiter zu erhöhen, werden die Passwörter gesalzen, mit einer 12-Bit Nummer, die das Passwort ergänzt (im String wird das Salz in den ersten beiden Zeichen abgespeichert). Dadurch gibt es für jedes Passwort 4096 Möglichkeiten, und der String, der nach Verschlüsselung mit ein und demselben Passwort entsteht, sieht jedesmal anders aus... Der DES Algorithmus ist so angelegt, daß ein Lawinen-Effekt eintritt. Kleinste Änderungen im Passwort, also dem Schlüssel, oder im Salz lösen eine riesige Veränderung im Algorithmus aus, mit entsprechender Auswirkung auf das Verschlüsselungs-Ergebniss.

Klarmachen muß man sich, daß das Passwort der Schlüssel ist, und das ein Feld von Nullen mit diesem Schlüssel verschlüsselt wird. Wenn der Algorithmus durchlaufen ist, so wird im Fall der Unix-Passwörter das Ergebnis (der 64-Bit Block) in ein 64 Zeichen Alphabet (a-zA-Z./). Bei dieser Translation werden verschiedene Werte auf dasselbe Zeichen abgebildet. Daher kann man im Spezialfall der Unix-Passwörter diese nicht wieder aus dem Ergebnis des Algorithmus zurückrechnen.

Aussehen tut das dann so:

Schlüssel: 64 Bit, jedes 8. Bit wird ignoriert => 56 Bit
Druckbare Zeichen je 6 Bit => 2 Zeichen Salz, 11 Prüfsumme

64 Bit Nullen                                 Schlüssel 56 Bit
0 0 0 0 0 0 0 0                           
0 0 0 0 0 0 0 0                         Shift              Shift
0 0 0 0 0 0 0 0                         28 Bit             28 Bit
0 0 0 0 0 0 0 0                      (Verschränkung um 1 oder 2 Bit)
0 0 0 0 0 0 0 0                      (Wird zu Schlüßel kombiniert) 
0 0 0 0 0 0 0 0                      (Für nächste Runde)
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0                             Kompression auf 48 Bit 
                                                       |
                                                       |
                                    

Permutation
(einfaches Verschieben)


Links                                    Rechts
32 Bit                                   32 Bit
                                            ----------------------
                                                                 |
                                         Expansion
                                         Permutation
                                         32 ==> 48 Bit
                                         (Erfolgt nach 
                                         Schema, Bits 
                                         werden wiederholt)
                                                       |
                                           XOR   +  ---|

                                            S-Box
                                            6 Bit => 4 Bit
                                          48 ==> 32 Bit

                                             Permutation

                        +

                  Rechts neu                                   Links neu
                                   
                                      nächste Runde

                                  Schlußpermutation
0 1 1 1 0 1 0 0 
1 0 0 0 1 0 1 0 
1 0 1 1 1 0 1 0 
1 0 1 0 1 0 1 0 
0 0 0 1 0 1 0 1 
1 0 0 0 1 0 1 0 
0 1 0 0 0 1 0 1 
0 1 0 1 1 1 0 0 


Konvertierung in 64-Zeichen ASCII (A-Z,a-z,".","/") 
Abspeichern in /etc/...

S-Boxen: Eine Tabelle mit 16x4 Zellen.
Eine Zelle ist eine 4 Bit Zahl.
Die 6 Bit zeigen auf die Zelle.

Wie wird die Wiederbenutzung von Passwörtern verhindert?

Bei AIX wird für die User in der Datei /etc/security/user die Zeile mit dem Schlüsselwort "histsize" eingeführt.

 
ormtest:
        admin = false
        histsize = 4
Mit dieser Einstellung werden die letzten 4 Passwörter gespeichert, und jedes neue Passwort wird gegen diese Information geprüft. Abgelegt werden diese Passwörter in binären Index-Files, ähnlich wie bei NIS:
 
root@e20test/etc/security# file pwdhist.*
pwdhist.dir:	empty
pwdhist.pag:	data or International Language text
Das File pwdhist.pag ist das interessante File.
 
root@e20test/etc/security# strings pwdhist.pag
Wj02Jm3/VR172>/ 
kRaJfPGQ4QmA6>/  LpSIzF7ow8xn6ormtest
Das aktuelle Passwort steht an erster Stelle, wie man leicht prüfen kann (/etc/security/passwd).
 
ormtest:
        password = Wj02Jm3/VR172
        lastupdate = 1043315344
        flags = 
Setzt man jetzt zweimal ein neues Passwort, dann wird das älteste Passwort gelöscht (die Länge der History ist ja 4..).
 
root@e20test/etc/security# strings pwdhist.pag
>/ joRJc8huzJvfIY>/ A3RBHyml2v71Rw>/
Wj02Jm3/VR172>/ kRaJfPGQ4QmA6ormtest
Das Passwort, welches "LpSIzF7ow8xn6" entspricht, kann ich also jetzt wieder einsetzen.

Wie kann ich ein beliebiges Passwort mit verschiedenen Salt-Werten erzeugen?

Mit folgendem Program:

 
/* Routine to encrypt a plain password using a given salt value.
 *
 * Usage cryptpw plain-password salt-value
 *
 * John Roebuck 09/02/2001
 */

#include 
#include 

main(int argc,char *argv[])
{
char    *crypass;

if (argc < 3)
        {printf("\nUsage   %s plain-password salt-value\n", argv[0]);
         printf("Example %s letmein zx\n\n", argv[0]);
         exit(1);}

crypass=crypt(argv[1],argv[2]);

printf("%s\n", crypass);
}
Ich setze jetzt zB. das Passwort testy für einen User. In der /etc/security/user finde ich das verschlüßelte Passwort und sehe, das Salt ist Wj.
 
ormtest:
        password = Wj02Jm3/VR172
        lastupdate = 1043315344
        flags = 
Das kann ich jetzt auf jeder beliebigen Maschine durch das crypt-Programm laufen lassen, es kommt immer dasselbe heraus.
 
root@CWS15:/tmp # ./cryptpw testy Wj
Wj02Jm3/VR172


[ Main | Local ]

[ Allgemein | UNIX | AIX | TCP-IP | TCP | ROUTING | DNS | NTP | NFS | FreeBSD | Linux | SMTP | Tracing | GPS ]

Copyright 2001-2014 by Orm Hager - Es gilt die GPL
Feedback bitte an: Orm Hager (orm@doc-tcpip.org )