Delphi-PRAXiS
Seite 1 von 7  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Passwort-Stärke ermitteln (Code und Prüflogik) (https://www.delphipraxis.net/154619-passwort-staerke-ermitteln-code-und-prueflogik.html)

Satty67 17. Sep 2010 23:39


Passwort-Stärke ermitteln (Code und Prüflogik)
 
Hallo,

in mein aktuelles Projekt bekommt ja einen verschlüsselten Dokumenten-Container. Für die Passwortwahl will ich dem Benutzer ein Hilfe geben, wie gut das gewählte Passwort ist. Dazu hab' ich im Internet viele Theorien gelesen und natürlich PassphraseQuality aus der Codelib ausprobiert.

Erst schien mir PassphraseQuality perfekt, wobei mir dann insbesondere bei der Passwortlänge ein merkwürdiges Verhalten aufgefallen ist. "Satty67!" wird mit 21% bewertet, während "Sattttttttttttttttttttttttttttttttttty67!" unter 5% liegt (wie kann das schlechter sein?).

Dann "TheQuickBrownFoxJumpsOverTheLazyDog" bekommt 100% während "TheWeatherIsWet,WhenTheWeatherIsWet!" nur 55% erhält. Beide Passwörter sind gleich lang, nur das Erste enthält lauter unterschiedliche Buchstaben. Allerdings denke ich, dass die Sonderzeichen höher zu bewerten sind, denn bei einer BruteForce-Attacke ist der eigeschränkte Buchstabensatz ja nicht bekannt (A-Z wir immer geprüft). D.h. es wird auch etwas zuviel Wert auf unterschiedliche Zeichen gelegt, wobei die zusätzliche Verwendung von Sonderzeichen keinen verstärkenden Einfluß hat.

Lange Rede, kurzer Sinn, ich hab' mir selber was überlegt :stupid:
  • Zeichenwiederholungen werden bei der Bewertung ignoriert und als Einzelzeichen gewertet, die restlichen Zeichen aber dadurch nicht abgewertet.
  • Bei erkanntem Datum werden die Punkte nicht als wertvolle Sonderzeichen gewertet
  • Prüfen, ob der Zeichensatz breit genutzt wird (Also Ziffern, Groß/Kleinbuchstaben, Sonderzeichen). Mindestens ein Zeichen der Gruppe ist nötig, um eine evtl. Attacke zu einem erweiterten Suchbereich zu zwingen.
  • Anzahl unterschiedliche Zeichen im Verhältnis zur Länge ermitteln (nicht extrem hoch bewertet)
  • Passwörter, die nur aus Buchstaben bestehen, abwerten (vermutetes Wort einer Sprache)
  • Gesamtlänge bewerten (Länge schätze ich bis zu einer Obergrenze am wichtigsten ein)
  • Die ganzen Einzelergebnisse ins richtige Verhältnis setzen
Ergebnis der Funktion ist hier auch ein Wert zw. 0.0 und 1.0 (zur besseren Vergleichbarkeit). Später werde ich wohl gleich ganze Prozente übergeben, damit man es gleich ohne Umrechnen einer ProgressBar o.ä. übergeben kann.

Alles in allem bin ich über das Bewertungsergebnis glücklicher, allerdings kenne ich nicht die Techniken im Detail, die bei einer Attacke angewendet werden. Deshalb kann ich mich bei der Bewertung eines Passwortes auch irren!

ToDo:
  • TopTen-Passwörter abwerten, wenn das dann in ein TPasswordEdit kommt, per Property setzbar
  • Keyboard-Layout: QWERTZ und CO, was Hagen bei sich implementiert hat

Der Code wird später in einer Komponente verbaut und ist nur zu besseren Prüf-/Tesbarkeit hier als Funktion vorgestellt. Kann es auch später als Einzelklasse aufbauen, das ist fix gemacht. Nach derzeitigem Diskussionsstand ist man aber noch nicht von der Qualität des Prüfergebnisses überzeugt, weshalb es sich noch nicht lohnt da etwas zu entwerfen.
Delphi-Quellcode:
function PasswordStrength(const Password : String): Extended;
const
  LowerMultiplicator  = 1.9; // Verhältnisse der 4 Zeichengruppen untereinander
  UpperMultiplicator  = 2.1; // und Anteil am Gesamtergebnis
  NumericMultiplicator = 1.5; // In der Summe etwa 10 scheint ausgewogen
  SignMultiplicator   = 2.5;
  DiffCharsMaxMulti   = 10; // Entropische Prüfung [schwach 10 - 100 stark]
  MinPasswordLength   = 4; // Ein kürzeres Passwort fällt völlig durch
  MaxPasswordLength   = 32; // Ein längeres Passwort verbessert nicht mehr das Ergebnis

  // Zeichenwiederholungen (da wenig Wert) entfernen
  function RemoveRepetitions(const AString : string): String;
  var
    i : Integer;
  begin
    Result := AString;
    i := 2;
    while i <= Length(Result) do
    begin
      if Result[i] = Result[i-1] then
        Delete(Result, i, 1)
      else
        inc(i);
    end;
  end;

  // Sofern ein Datum erkannt wird, wertlose Separatoren entfernen
  function RemoveDateSeparator(const AString : string): String;
  var
    i : Integer;
    dt : TDateTime;
    DateStr : String;
  begin
    DateStr := AString;
    i := Length(DateStr);
    if (i > 0) and (AString[i] = DateSeparator) then
      Delete(DateStr, i, 1);

    if TryStrToDate(DateStr, dt) then
      Result := StringReplace(AString, DateSeparator, '', [rfReplaceAll])
    else
      Result := AString;
  end;

  // Längen-Multiplikator mit Rücksicht auf Obergrenze
  function LengthMul(const CurrentLength, MaxLength : Integer): Extended;
  begin
    if CurrentLength > MaxLength then
      Result := Math.Log2(MaxLength) * Math.Log2(MaxLength)
    else
      Result := Math.Log2(CurrentLength) * Math.Log2(CurrentLength)
  end;

  // Bewerten der im Passwort verwendeten Zeichen
  function CalculateEntropie(CleanPWLength, DiffCharsCount : Integer;
                  LowerMul, UpperMul, NumericMul, SignMul: Extended):Extended;
  begin
    Result := (DiffCharsCount * DiffCharsMaxMulti) / CleanPWLength;
    if (NumericMul + SignMul) = 0 then
      Result := Result + ((LowerMul + UpperMul) / 2)
    else
      Result := Result + LowerMul + UpperMul + NumericMul + SignMul;
  end;

  // Maximal ereichbares Ergebnis für Prozentrechnung ermitteln
  function GetBestResult: Extended;
  begin
    Result := CalculateEntropie(1, 1, LowerMultiplicator, UpperMultiplicator,
                                NumericMultiplicator, SignMultiplicator);
    Result := Result * LengthMul(MaxPasswordLength, MaxPasswordLength);
  end;

var
  i, CleanPWLength : Integer;
  CleanPassword,
  DiffChars : String;
  EntropieMul,
  LowerMul, UpperMul,
  NumericMul, SignMul : Extended;
begin
  Result    := 0;
  LowerMul  := 0;
  UpperMul  := 0;
  NumericMul := 0;
  SignMul   := 0;

  CleanPassword := Trim(Password);
  CleanPassword := RemoveDateSeparator(CleanPassword);
  CleanPassword := RemoveRepetitions(CleanPassword);

  CleanPWLength := Length(CleanPassword);
  if (CleanPWLength >= MinPasswordLength) then
  begin

    for i := 1 to Length(CleanPassword) do
    begin
      case CleanPassword[i] of
        'a'..'z': LowerMul  := LowerMultiplicator;
        'A'..'Z': UpperMul  := UpperMultiplicator;
        '0'..'9': NumericMul := NumericMultiplicator;
      else
        SignMul := SignMultiplicator;
      end;

      if Pos(CleanPassword[i], DiffChars) < 1 then
        DiffChars := DiffChars + CleanPassword[i];
    end;

    EntropieMul := CalculateEntropie(CleanPWLength, Length(DiffChars),
                                     LowerMul, UpperMul, NumericMul, SignMul);

    Result := EntropieMul * LengthMul(CleanPWLength, MaxPasswordlength);
    Result := Result / GetBestResult;
  end;
end;
Der Vollständigkeit halber ein Anwendungsbeispiel:
Delphi-Quellcode:
procedure TForm1.Edit1Change(Sender: TObject);
begin
  Label1.Caption := Format('Sicherheit bei annähernd %.1f%%',
                           [PasswordStrength(Edit1.Text) * 100]);
end;

Luckie 17. Sep 2010 23:48

AW: Passwort-Stärke ermitteln (Code und Prüflogik)
 
Also was mir da auf an Hieb für ein Stichwort einfällt ist Entropie. Eventuell kannst hilft es dir bei deinen Recherchen. So wohl im physikalischem Sinne http://de.wikipedia.org/wiki/Entropi...ermodynamik%29 (Maß der "Unordnung") als auch im Sinne der Informatik http://de.wikipedia.org/wiki/Entropi...ionstheorie%29 (Maß der Informationsdichte). Dabei gehe ich davon aus, dass je größer die Unordnung ist, desto sicherer sollte das Passwort sein. Gleiches gilt für die Informationsdichte.

Satty67 17. Sep 2010 23:55

AW: Passwort-Stärke ermitteln (Code und Prüflogik)
 
Spezialisierte Algorithmen oder Theorien kenne ich nur wenige, da sind bei mir Stichwörter (für Google) immer hilfreich. :wink:

Ich hatte versucht mir eine Attacke auf ein Passwort vorzustellen bzw. was ein ermitteln schwer macht. Dabei kenne ich ja nicht alle Techniken. Dabei bleibe ich meistens bei BruteForce-Attacken hängen, welche durch eine möglichst hohe Zahl der Testläufe erschwert werden können.

Ich hab' aber gelesen, das es inzw. auch kombinierte Attacken gibt, die mit dem Hash (MD5 oder SHA) zusammen da gezielter angreifen.

Luckie 17. Sep 2010 23:58

AW: Passwort-Stärke ermitteln (Code und Prüflogik)
 
Experte bin ich auch nicht, aber das war was mir dazu eingefallen ist. Aber schreibe Hagen doch mal eine PN oder E-Mail und weise ihn auf deine Entdeckung hin.

Satty67 18. Sep 2010 00:09

AW: Passwort-Stärke ermitteln (Code und Prüflogik)
 
Wenn sich nicht rausstellt, das ich irgendeinem Irrtum aufgelaufen bin (wie so oft) kann/werde ich das machen.

BUG 18. Sep 2010 00:16

AW: Passwort-Stärke ermitteln (Code und Prüflogik)
 
Zitat:

Zitat von Satty67 (Beitrag 1050374)
"Satty67!" wird mit 21% bewertet, während "Sattttttttttttttttttttttttttttttttttty67!" unter 5% liegt (wie kann das schlechter sein?).

Wenn man sich Hagens Verfahren anschaut, ist die Entropie dort sehr wichtig (ist ein Faktor).

Die Entropie von "Sattttttttttttttttttttttttttttttttttty67!" ist viel geringer als die von "Satty67!", da ja das 't' überdurchschnittlich häufig vertreten ist.

Satty67 18. Sep 2010 00:30

AW: Passwort-Stärke ermitteln (Code und Prüflogik)
 
Ja aber das ist dem Angreifer ja nicht bekannt. Die Frage ist, ob solche 20 "T"s innerhalb des Passwortes einen Angriff leichter oder schwerer machen (weil die Länge größer wird).

Ich bin zwar nicht sicher, aber tendiere eben dazu, dass das Passwort dadurch etwas besser wird, aber auf keinen Fall um 15% schlechter. (In weiterer Kombination mit anderen zeichen eben deutlich besser, da hier der Längenvorteil eine Rolle spielt)

Anders gefragt:

ist "abcd" sicherer als "tttttttttttttttttt", wenn ein Angreifer keinen Hinweis auf die simple Art des Passwortes hat? Das ist wohl entscheidend für die Frage, ob ich auch eine entropische Komponente mit einarbeiten müsste.

Dazu ein Zitat:
Zitat:

Zitat von negaH (Beitrag 90789)
...primär entscheidet erstmal die Länge des Passwortes ob es gut oder schlecht ist. D.h. ein langes Passwort muß viel mehr gewichtung erhalten als ein kurzen Passwort. Ein um 1 Zeichen längeres Passwort sollte niemals schlechter bewertet werden als ein kombinatorisch gesehen besseres aber kürzeres Passwort...

...was aber bei dem Sat...ty67 Beispiel der Fall ist!?

Sir Rufo 18. Sep 2010 07:37

AW: Passwort-Stärke ermitteln (Code und Prüflogik)
 
Es kommt auf das Einsatzgebiet des Passwortes an ob die Entropie mehr oder weniger kritisch ist.

Wird das Kennwort als Hash gespeichert (worauf der Angreifer Zugriff hat) dann sind viele sich wiederholende Zeichen nicht ganz so schlimm, außer:

- das Kennwort besteht nur aus einem Buchstaben "tttttttt"
- der Angreifer hat mitbekommen (über die Schulter geschaut) das hauptsächlich ein "t" im Kennwort vorkommt

Wird das Passwort direkt als Schlüssel benutzt (z.B. WPA2-Key) so ist die Verschlüsselung mit "tttttttt" schlechter als mit einem "bunten" Passwort.

Die Entropie ist also auch ein Gradmesser für "Ausspähsicherheit" und "Verschlüsselungsgüte".
Somit sehe ich die Entropie als durchaus entscheidend an.

Beim reinen Schutz gegen Brute-Force-Attacken ist sicherlich die Länge ausschlaggebend "Size matters", aber die Realität kennt mehr als Brute-Force.

Satty67 18. Sep 2010 08:52

AW: Passwort-Stärke ermitteln (Code und Prüflogik)
 
Gut, ich will sowieso noch ein paar Subfunktionen einbauen, die spezielle Eigenschaften prüfen und dann abwerten.
  • Datum: Punkte und Striche ect. werten bei mir in dem Fall noch zu sehr das PW auf
  • TopTen: Wenn eines der häufig genutzen Passwörter eingegeben wird
  • Keyboard-Layout: QWERTZ und CO, was Hagen bei sich implementiert hat
  • Entropie: Allerdings etwas anders...

"Satttttttty" kann nicht schlechter sein als "Satty", es ist mindestens gleichwertig. Ich habe mir überlegt, das Wiederholungen ausschneide, bevor das Passwort mit den restlichen Methoden bewertet wird. z.B. ab der 3ten Wiederholung ausschneiden... ein "ttttttttt" wird dann wie "tt" bewertet und "Sattttttttty" wie "Satty"

Edit:

So, Wiederholungen werden ab dem 2ten Zeichen nun bei der Bewertung ignoriert. "Satty" und "Satttttttty" wird beides wie "Saty" bewertet. Eine höhere Last auf Entropie kann man durch Erhöhen der Konstante DiffCharsMaxMulti erreichen.

Ich denke es ist ein Kompromiss, der den Längenvorteil von vielen gleichen Zeichen zwar ignoriert, die restlichen Zeichen im Passwort aber durch Wiederholungen nicht abwertet?

Edit #2:

So, etwas umgebaut und Namen angepasst. Ich muss aufpassen, dass das ganz nicht zu aufwändig wird. Ist im Prinzip ja nur ein Vorschlag-Geber und sollte die Zeicheneingabe auf langsamen Rechnern nicht bremsen :stupid:

Ganz ehrlich, ich bin mit Auswertungsergebnis ziemlich zufrieden. Hagen hat mit Sicherheit die cryptologisch besseren Prüfmethoden verwendet, aber imho eben an einer Stelle einen Fehler drin oder zumindest ein seltsames Verhalten.

sx2008 18. Sep 2010 13:56

AW: Passwort-Stärke ermitteln (Code und Prüflogik)
 
Immer wenn ich solche komplexen Funktionen mit jeder Menge Unterfunktionen sehe,
dann klingelt bei mir ein kleines Glöckchen:
"hey, du solltest hier besser eine Klasse draus machen!"

Und wenn ich dann noch lese: "Gut, ich will sowieso noch ein paar Subfunktionen einbauen..."
dann bin ich mir sicher, dass hier eine Klasse benötigt wird.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:12 Uhr.
Seite 1 von 7  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz