Entwickler-Ecke

Sonstiges (Delphi) - Passwort verschlüsseln und wiedererkennen


Flamefire - Fr 23.01.09 15:11
Titel: Passwort verschlüsseln und wiedererkennen
Ich hab da mal folgendes Problem:
In einem Programm von mir sollen u.a. Passwörter gespeichert werden, die Passwörter werden mit einem Masterpasswort gesichert, dass aber eher für einen andere Zweck ist und sonst nichts damit zu tun hat.
Die gespeicherten Passwörter sollen dann i-wo eingegeben werden. (Man sieht das PW nicht im Klartext!)
Das Problem nun: wie erkenne ich, ob die Entschlüsselung fehlgeschlagen ist?
Es ist nämlich möglich, dass gespeicherte (verschlüsselte) Passwort zu ändern, bzw den Masterkey zu ändern. Und dann würden die PWs falsch eingegeben werden.
Das will ich verhindern.

Aber wie kann ich bei einem zufälligem Passwort sicher erkennen, ob die Entschlüsselung geklappt hat?
Checksummen davor setzen, bevor es verschlüsselt wird? (vl die erste 2 Bytes einer SHA1 oder CRC-Summe) Und das ganze durch ein 00-Byte vom Rest abtrennen.


Und: Ja ich weiß, dass die Sicherheit dadurch gefärdet wird, aber das ist ne ganz so schlimm wie falsche PWs


BenBE - Fr 23.01.09 15:44

Du verschlüsselst nicht die Passwörter an sich mit dem Masterkey, sondern verschlüsselst den Key zum Lesen der Passwörter mit dem Masterkey. Wenn Du den Masterkey danach änderst, brauchst Du nur die Verschlüsslung des Passwort-Keys zu aktulisiern (diesen neu zu verschlüsseln). Zum Prüfen könntest Du einen Hash der zu (entschlüsselten) Informationen (verschlüsselt) speichern.

Hinweise, warum der Hash mit verschlüsselt werden sollte, findet man im Internet zu hauf; ergibt sich aber auch rein logisch ;-)


Flamefire - Fr 23.01.09 18:47

das problem: der masterkey ist ein passwort auf einer webseite, dass auf der webseite geändert wird...
ich kann also die änderung nicht im programm mitbekommen

dein vorschlag geht also leider nicht
das mit dem verschlüsseltem hash könnte ich machen

ich würde also:
pw-->hash(pw)+00+pw-->verschlüsselt(hash(pw)+00+pw)

entschlüsselung:
entschlüsseln(cipher)->trenne nach 00 und prüfe hash mit hash vom rest

oder wie soll ich das machen?


BenBE - Fr 23.01.09 19:03

Nein, du nutzt zwei Schlüssel:
1. Key zum Verschlüsseln der Passwörter
2. Schlüssel zum Schutz des 1. Schlüssels

Verschlüsslung eines neuen Passwortes:
1. Benutzer gibt Masterpasswort an
2. Programm meldet sich mit diesem Masterpasswort auf der Website an
3. Programm erhält von der Website den Key für seiner Passwörter
4. Programm verschlüsselt das neue Passwort mit diesem Schlüssel
5. Das Programm vergisst jegliche unverschlüsselten Daten sowie den von der Website erhaltenen Schlüssel

Lesen eine Passwortes:
1. Benutzer gibt das Masterpasswort ein
2. Benutzer wählt aus, welches Passwort er haben möchte
3. Programm meldet sich mit diesem Masterpasswort auf der Website an
4. Programm erhält von der Website den Key für seiner Passwörter
5. Das Programm entschlüsselt entschlüsselt die Passwörter
6. Das Programm überprüft die Entschlüsslung indem es den (zusätzlich) entschlüsselten Hash überprüft.
7. Das Programm vergisst den Schlüssel von der Website, sowie alle andren Daten, die nicht mehr Funktionsrelevant sind.

Jetzt klar?


Flamefire - Sa 24.01.09 00:07

hm. könnte ich machen.
das lesen der passwörter sollte aber sehr schnell gehen, ohne erst eine serververbindung aufbauen zu müssen

nja mal sehn

wie mache ich das ganze mit dem hash? wo kommt der hin? und wie unterscheide ich den vom pw?


BenBE - Sa 24.01.09 01:51

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
hm. könnte ich machen.
das lesen der passwörter sollte aber sehr schnell gehen, ohne erst eine serververbindung aufbauen zu müssen

Wenn dein Masterpasswort auf dem Server steht, musst Du auch zum Lesen der Passwörter auf dem Server nachfragen, wie der Schlüssel ist. Man kann das oben beschriebene Vorgehen aber dahingehend abändern, dass man sich diesen Session-Schlüssel für die Sitzung merkt und damit nur beim ersten Abruf Verbindung zum Server aufnimmt. Das hat zudem aus Datenschutzgründen Vorteile.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
wie mache ich das ganze mit dem hash? wo kommt der hin? und wie unterscheide ich den vom pw?

Bau dir da einfach eine kleine Datenstruktur, die das ganze verwaltet. Das könnte z.B. so hier aussehen:

Quelltext
1:
Hash + Dummy + PWStruct1 + PWStruct2 + ... + PWStructN                    

Wobei PWStruct so hier aussehen könnte:

Quelltext
1:
StructLen + Len1 + PWUsageRealm + Len2 + PWUsername + Len3 + PWPasswordString                    

Wobei StructLen die Anzahl der Bytes angibt, die in dieser Struktur folgen:

Delphi-Quelltext
1:
StructLen = (Len1 + Len2 + Len3)*SizeOf(Char) + 3*SizeOf(Integer)                    

Vorausgesetzt, Len1..3 werden als Integer gespeichert.

Hash ist dabei der Hashwert über alle folgenden Informationen und Dummy eine Pseudozufällige Zahl, die bei jeder Änderung der Daten auch geändert werden sollte. Zur Verschlüsslung solltest Du dabei einen Verschlüsslungsalgorithmus im CBC\CBF-Modus (Cipher Block Feedback\Chaining) nutzen; daher auch der Hinweis, den Dummy-Wert regelmäßig zu ändern, da ansonsten leicht Rükschlüsse auf die enthaltenen Daten gemacht werden könnten (wenn z.B. ein bestimmter Eintrag geändert wurde).


Flamefire - Sa 24.01.09 14:34

ok das sieht schonmal super aus
trotzdem noch ein 2 fragen:
1) was ist PWUsageRealm ?
2) das ganze muss in einer ini-datei gespeichert werden. ich würde also eine base64-encoder drüber jagen, bevor ich es speichern kann
wie zerlege ich das am besten in die structur?
als erstes muss ich es ja base64-decodieren. dann habe ich ein byte-array oder string (ist ja fast das gleiche)
sollte ich das dann erst in eine strucur (record typ) zerlegen?
ich würde es so machen:
a)base64Decode
b)entschlüsseln mit sessionPW
c)ergebnis auser hash in die hash-funktion schicken und per pointer mit dem hash vergleichen
d)dann strcutlen und die einzelnen längen (wieder per PInteger()^) abgleichen
e)wenn alles ok ist, die einträge per PChar() extrahieren
Ist das so richtig?


BenBE - Sa 24.01.09 14:37

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
ok das sieht schonmal super aus
trotzdem noch ein 2 fragen:
1) was ist PWUsageRealm ?

Der Verwendungszweck für das Passwort. Bei einem Browser z.B. für welche Website das PW gültig ist.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
2) das ganze muss in einer ini-datei gespeichert werden. ich würde also eine base64-encoder drüber jagen, bevor ich es speichern kann
wie zerlege ich das am besten in die structur?

Schau dir mal Streams an. Damit geht das recht praktisch.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
als erstes muss ich es ja base64-decodieren. dann habe ich ein byte-array oder string (ist ja fast das gleiche)
sollte ich das dann erst in eine strucur (record typ) zerlegen?
ich würde es so machen:
a)base64Decode
b)entschlüsseln mit sessionPW
c)ergebnis auser hash in die hash-funktion schicken und per pointer mit dem hash vergleichen
d)dann strcutlen und die einzelnen längen (wieder per PInteger()^) abgleichen
e)wenn alles ok ist, die einträge per PChar() extrahieren
Ist das so richtig?

Jap.