Benutzerpasswörter sicher UND im Klartext auslesbar speichern?

trench140

Mitglied
Mahlzeit,

ich habe die Aufgabe bekommen, eine neue Administrationsoberfläche zu entwickeln.
Mit dieser soll man z.B. User anlegen können. Eine Anforderung ist hierbei, dass man (als Admin) die User-Passwörter auch im Klartext auslesen kann. Über Sinn und Unsinn braucht man nicht zu diskutieren, das ist halt eine Vorgabe und damit muss ich leben :)

Nun habe ich mir überlegt, wie ich das Ganze trotzdem sichern kann und hatte dabei die folgende Idee:

Ganz zu Anfang wird der Admin-User angelegt. Hierbei wird zunächst wie folgt ein Salt erzeugt, daraufhin mit dem Passwort zusammengefügt und anschließend das Ganze nochmal gehasht:

PHP:
$admin_pass='tollespasswort';
$admin_salt = hash('sha256',microtime());
$admin_salted_pw = $admin_pass.$admin_salt;
$admin_hashed_pw = hash('sha256',$admin_salted_pw);

Anschließend speichere ich $salt und $hashed_pw in der Datenbank. Das Ganze soll übrigens für die User genauso laufen, nur dass hier eben noch ein Feld dazukommen soll, in dem ich das Passwort VERSCHLÜSSELT speichere.

Hierzu nehme ich den User-Salt, und packe ihn zum Admin-Passwort hinzu. Anschließend bilde ich darüber einen Hash und verschlüssele mit diesem das ursprüngliche Passwort:

PHP:
$user_pass = 'bla';
$user_salt = hash('sha256',microtime());
$user_salted_pw = $user_pass.$user_salt;
$user_hashed_pw = hash('sha256',$user_salted_pw);

$user_salted_key = $admin_pw.$user_salt;
$user_hashed_key = hash('sha256',$user_salted_key,true);

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$user_crypt_pass = mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$user_hashed_key,$user_pass,MCRYPT_MODE_CBC,$iv);

$user_crypt_pass wird dann in dem Tabelleneintragdes Users gespeichert.

Wie sicher oder unicher ist diese Methode?

Ich weiß, ich schieße hier ein wenig mit Kanonen auf Spatzen, aber ich möchte einfach aus Prinzip gerne starke Hash- und Verschlüsselungsalgorithmen einsetzen.

Die Idee hinter meiner Überlegung war, dass jemand, der Zugriff auf die Datenbank bekommt keine verwertbaren Daten bekommt.

Überlegungen:
1. Für SHA256 wurden im Vergleich zu MD5 und SHA1 noch keine schwerwiegenden Schwächen gefunden.

2. Die Wahrscheinlichkeit einer Kollision ist bei 256 Bit weit niedriger

3. AES ist DER Standard für symmetrische Verschlüsselung, Bruteforce lohnt sich schon in der 128-Bit-Variante nicht.

4. Durch die Wahl von AES-256 kann ich den kompletten SHA256-Hash als Passwort nehmen.

So, die letzte Frage, was wäre, wenn nun wirklich jemand Zugriff auf die Datenbank erhält. Dann kann er ja z.B. auch den Salt des Admin-Passwortes auslesen. Wenn er dann noch weiß, wie der Salt angewendet wird, kann man ja wieder "einfach" eine Rainbow-Table erstellen. Allerdings gehe ich davon aus, dass ein Salt nur solange wirksam ist, wie jemand keinen Zugriff auf den Algorithmus hat, der ihn anwendet, oder? Ich meine, wenn Datenbank und Webserver auf getrennten Maschinen laufen und dann jemand auf beide Zugriff hat, dann liegt ja schon ganz woanders etwas im Argen, oder?

Unter der Annahme könnte ein Angreifer dann nämlich Admin-Salt und Admin-Hash kriegen, aber nicht das Admin-Passwort. Und ohne dieses könnte er die User-Passwörter nicht entschlüsseln. Und selbst bei erfolgreichen Kollisionsangriffen (solange nicht das Originalpasswort gefunden wird) wäre das Ganze auch resistent, da es spätestens hier:
PHP:
$user_salted_key = $faked_admin_pw.$user_salt;
$user_hashed_key = hash('sha256',$user_salted_key,true);
$user_plain_pass = mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$user_hashed_key,$user_crypt_pass,MCRYPT_MODE_CBC,$iv);

echo $user_plain_pass; // Blödsinn vom Feinsten
knallen würde.
 
Ganz zu Anfang wird der Admin-User angelegt. […] Anschließend speichere ich $salt und $hashed_pw in der Datenbank.

[…]

Die Idee hinter meiner Überlegung war, dass jemand, der Zugriff auf die Datenbank bekommt keine verwertbaren Daten bekommt.
Erkennst du die Ironie dieser Aussage? Das ist wie die berühmte PIN auf der Rückseite der Bankkarte.
 
Moin,

das war ja grad die Kernfrage. Bei allen Howtos usw. findet sich aber der Vermerk, dass man eben Hash(PW+Salt) UND Salt speichern muss, da der Salt ja zufällig gewählt und nicht reproduzierbar ist.

Und eben dadurch wird der Salt ja wieder sinnlos, es sei denn, die zusätzliche Sicherheit basiert eben wirklich nur darauf, dass der Angreifer NICHT weiß WIE der Salt mit dem Passwort verwurstet wird.

Gruß,
Trench
 
Das ist schon richtig. Nur wenn du wie in diesem Fall den Schlüssel, der zur Ver- und Entschlüsselung benötigt wird, ebenfalls in der Datenbank speicherst, ist die Verschlüsselung nutzlos, da eine Verschlüsselung ja auf der Geheimhaltung ebendieses Schlüssels beruht.
 
Bei jedem Login bekommst du das Passwort im Klartext geschickt.
Nutze die Gelegenheit und generiere einen neuen Salt + Hash.
 
@Gumbo:
Nee, den Schlüssel selber speicher ich nicht. Den berechne ich erst, wenn ich mich als Admin eingeloggt habe.

Ich nehme das Admin-Passwort, dass ja beim Login so oder so eingegeben wurde, wende darauf den Salt von User X an, hashe das Ganze und das Ergebnis nehme ich dann zum ver- und entschlüsseln des Schlüssels von User X.

In der Datenbank habe ich für den Admin also nur

AdminSalt
Hash(AdminPW+AdminSalt)

Für die User

UserXSalt
Hash(UserXPW+UserXSalt)
crypt(UserXPW,Hash(AdminPW+UserXSalt))

War vielleicht etwas missverständlich erklärt.

@Felix:
Das hört sich interessant an, dahingehend könnte ich noch überlegen :)
 
Das Problem an deinem System sehe ich, dass nur das Administrator-Passwort herausgefunden werden muss und damit dann sämtliche anderen Passwörter einfach entschlüsselt werden können. Ist das sicher?
 
Hi,

ja, das stimmt natürlich, das ist mir auch durchaus bewusst. Problematik ist wirklich, dass ein System benötigt wird, mit dem man die User-Passwörter, sofern nötig, im Klartext auslesen kann.

Es handelt sich übrigens nicht um persönliche Accounts sondern um Systemaccounts usw., falls jemand Bedenken wegen Datenschutz äussern möchte oder so :D

Das Ganze soll allerdings nur aus einem internen Netz erreichbar sein, trotzdem möchte ich lieber eine Verschlüsselung einbauen, als das Ganze einfach nur blauäugig im Klartext zu speichern.

Das Admin-Passwort wird natürlich dementsprechend gewählt, also Passwörter wie "geheim" oder "EM2008" wirds nicht geben ;)
 
Aber welcher Grund sollte das Speichern des Kennworts in verschlüsselter Form rechtfertigen? Mir fällt keiner ein. Wenn es vergessen werden sollte, wird einfach ein neues generiert.
 
Zurück