Programm testen

Du gibst mir einfach eine Exe und glaubst ich führe die ohne weiteres aus ? :rolleyes:

Nene, gib mal den Source. Dazu bist du erstens verpflichtet (GPL), und zweitens brauch ich den um das Programm bewerten zu können.
 
Hm, Delphicode liegt mir nicht wirklich...

Das einzige was ich auf die Schnelle sagen kann ist, dass dein Code mir zu unübersichtlich ist.

Mal ein paar Probleme die ich gefunden habe:
  • Generische Namen wie "TForm4.Button2Click"
  • Viel doppelter Code (z.B. 3 mal Encrypt, genau gleich)
  • Code der ähnliches macht (z.B. Edit1Enter, Edit2Enter: warum nicht die Funktion einmal und das TextField "Sender" leeren ?)
  • Passwörter würde ich als Array statt als String speichern, so kannst du sicherstellen dass der Speicher nach der Benutzung überschrieben wird.
  • Du scheinst nur eine Iteration des Hashes zu machen, ich würde mindestes einige 100000 machen.
  • Warum verwaltest du deine Daten alle als Strings wenn es eigentlich binäre Daten sind ?
  • Du packst alles in die Events der Controls. Ein bischen Abstraktion würde das übersichtlicher machen.
 
Code:
  salt1 := 'dsiad8204u80uei3et474848dh98bfdb46,4,.#ü#8+ü8q+ä#.vöäüoi0erw78974344256d46f#+545.8ghm+rü04äasmnfdnbn,463'; 
salt2 := '3786f74sdfd+#s.#+32ü,.sf,ß034,2üpfsd,ä,v,#öäb6oß4ü34,#bn#nßüüüüüü045ß0zk54kpüh,#üt#.h5+ß0isergkrgä9p43e-';

Salts sollten eigentlich immer zufällig sein. Wenn ein bestimmter salt hart-codiert wird der Salt nicht für jedes Passwort einzigartig ist, kann ich dennoch Rainbowtables erstellen. Du solltest allgemein für Passwörter entweder bcrypt, scrypt oder pbkdf2 nehmen.
 
Zuletzt bearbeitet:
Das ist aber gängige Praxis, denn wie willst du sonst ein Passwort auf seine Gültigkeit prüfen.

Wo ich dir jedoch rechtgebe ist das der Salt einmal zufällig generiert und gespeichert werden sollte.
Dies ist allerdings recht unnötig, da ich wenn ich einen Angriff gegen den Passwort-safe fahre, ich ohnehin zugriff auf das System habe.
Ein Salt ist dann in den Szenarien wichtig, wenn ich Passwörter in einem anderen System, z.B. einer Datenbank speichere und diese dann ggf. geklaut wird.
Abgesehen davon wird die Datenbank inklusive dem darauf operierenden Softwaresystem eher selten geklaut, oder meinetwegen zusätzlichen Keystorage.

In diesem Fall wäre eine Sicherung des Passwortes mit systeminternen Cryptofunktionen hilfreich, da diese die Schlüssel/Salts für den Benutzer unzugänglich aufbewahren können und man dann erst System knacken muss oder aber die einzelnen Systemkomponenten welche für den Salt herangezogen werden zusammentragen muss.

Was hier hielfreich ist ist eine Bremse im Programm welche Brute-Force-Angriffen vorbeugt.

Schlüssel-/Passwortmanagement ist grundsätzlich sehr kniffelig.

Gruß

Fluffy

P.s.:
Der Form halber, habe mir den Code so nicht angeschaut, und kann auch kein Delphi.
 
Übersichtlicher machen, in Form von mehre Funktion kann ich noch machen.

Du scheinst nur eine Iteration des Hashes zu machen, ich würde mindestes einige 100000 machen.
Es bringt doch nichts eine Zeichenkette mehrmals zu hashen. Oder täusche ich ich jetzt da?
 
Es bringt doch nichts eine Zeichenkette mehrmals zu hashen. Oder täusche ich ich jetzt da?
Nicht die Zeichenkette mehrmals, etwa so meine ich das:
Code:
hash = GenerateHash(password + salt)
for(i=0; i< 1000000; i++)
    hash = GenerateHash(hash + salt)
Dadurch machst du die Hashberechnung langsamer. Normale Hashes sind dafür designed schnell zu sein, und so wird es halt für jeden Hash eine millionenmal so lang brauchen.
Und ob ich 15 Mio. oder 15 hashes pro Sekunde berechnen kann ist ein großer Unterschied.
 
Das ist aber gängige Praxis, denn wie willst du sonst ein Passwort auf seine Gültigkeit prüfen.

Wo ich dir jedoch rechtgebe ist das der Salt einmal zufällig generiert und gespeichert werden sollte.

HeHe, ok! Hab mich falsch ausgedrückt. Der Salt muss natürlich vor dem Hash stehen, aber muss für jeden Hash neu mit einem PRNG generiert werden. Schneier spricht, glaube ich, auch nicht von zufällig, sondern von einzigartig. Ein PRNG wäre demnach nur ein Mittel, um die Einzigartigkeit annähernd zu erreichen.

Dies ist allerdings recht unnötig, da ich wenn ich einen Angriff gegen den Passwort-safe fahre, ich ohnehin zugriff auf das System habe.

Den Zusammenhang blick ich jetzt nicht. Der Salt ist dazu da, sich gegen Rainbowtables zu schützen. Dieser Schutz ist nur gegeben, wenn sich der Salt für das selbe Passwort unterscheidet. Klar wäre die Rainbowtable nur für das eine Programm geeignet, aber wenn das eine Programm sehr oft eingesetzt wird, lohnt sich die Generierung. Das ist beispielsweise der Knackpunkt bei WLANs, die über WPA gesichert sind. Die ESSID ist der Salt und beispielsweise lohnt es sich für die ESSID "dlink" Rainbowtables zu generieren.
Anyway, der Passwortspeicher ist auch nichts anderes als eine Datenbank für Passwörter, welche theoretisch auch auf einem anderen System liegen kann.

PBKDF2 bietet sowohl salt als auch zusätzliche iterationen an. Nutze es!
 
Zuletzt bearbeitet:
Datei: cMa - Zeile 121
Code:
     for z := 1 to 30 do begin
         ini.WriteString(hash, 'Benutzername'+inttostr(z), Encrypt(StringGrid1.Cells[s,z], salt));
         s := s + 1;
         ini.WriteString(hash, 'Passwort'+inttostr(z), Encrypt(StringGrid1.Cells[s,z], salt));
         s := s + 1;
         ini.WriteString(hash, 'SeitenURL'+inttostr(z), Encrypt(StringGrid1.Cells[s,z], salt));
         s := s + 1;
         ini.WriteString(hash, 'Anmerkung'+inttostr(z), Encrypt(StringGrid1.Cells[s,z], salt));
         s := 1;

     end;

Was machste denn, wenn du mal mehr als 30 Passwörter speichern willst? ;)
 
Code:
    if FileExists(path+'\PWHash.txt') then
    begin
        sl := TStringList.Create;
        sl.LoadFromFile(path+'\PWHash.txt');
        tmp := sl.CommaText;
        hash := tmp;
    end;
    salt := 'd09f9dßfsadfpdsjgdslkd98f9rr'+hash+'ffd+sar3+ür.a+üfe.+f3w';
    ini := TIniFile.Create(path+'\Passwort Manager.ini');
    s := 1;
    for z := 1 to 30 do begin
        ini.WriteString(hash, 'Benutzername'+inttostr(z), Encrypt(StringGrid1.Cells[s,z], salt));
        [...]
    end;

Für die Entschlüsselung reicht die Kenntnis des Hashs aus der PWHash.txt, was aufgrund fehlender Schutzmechanismen für diese Datei ein triviales Ziel ist. Er braucht also nicht das Master-Passwort, durch das der Hash erstellt wird, da ihm der (leicht zugängliche) Hash zur Entschlüsselung reicht.

Ein besserer Ansatz wäre die Verschlüsselung mittels Public Key Kryptographie. Hier könntest du z.B. eine PKCS12-Datei erstellen, die du mittels dem vom User erstellten, oder einem davon davon abgeleiteten, längeren Passwort schützt. Mit dem dazugehörigen Public Key kannst du nun die Passwörter sicher und einfach verschlüsseln. Hier könntest du z.B. auch auf Smartcards zurück greifen, um die Passwörter zu ver- bzw. entschlüsseln. Das gibt es auch meines Wissens noch nicht.
 
Zuletzt bearbeitet:
Im Grunde könntest du auch auf die Speicherung der Hashes verzichtent. Du nimmst das Passwort des Benutzers jagst es durch pbkdf2 und versuchst die mit twofish verschlüsselte Datenbank zu entschlüsseln. Wenn das klappt cool und wenn nur Bockmist bei rauskommt, war es wohl das falsche Passwort. :-P
 
Zurück
Oben