[regex] Passwortvalidierung

Sir Luckal0t

Lieutenant
Registriert
Okt. 2009
Beiträge
519
Halloho zusammen,

ich arbeite hin-und-wieder mit regular expressions, das ist aber jetzt schon so lange her, dass ich das gar nicht mehr kann. Und einfach fand ich das noch nie.
Ich möchte einen Passwortvalidator mittels regex (in Java mit @Pattern beim Mappen auf's Modell) realisieren.
Ich möchte mit dem regex gegen die folgende Passwortrichtlinie validieren:

Code:
- Mindestens 8 Zeichen
- Maximal 5 mal gleiches Zeichen im gesamten String
- Mind. 3 unterschiedliche Zeichengruppen sollen Verwendung finden aus diesen 4: 
- - Kleinbuchstaben
- - Großbuchstaben
- - Sonderzeichen : ^°!“§$%&/()=?`²³{[]}<>|@€µ,;.:-_#’+*~
- - Ziffern 

nice to have:

- Maximal 4 nebeneinanderliegende Zeichen (deutsche Tastatur) (bspw: [qwer] ist ok, [qwert] wird abgelehnt)

Kann das vielleicht jemand aus dem FF? =)

Danke und Grüße,

Anon
 
Zuletzt bearbeitet:
Ich bin zwar damals in theoretischer Informatik durchgefallen, aber meine Intuition sagt mir, dass reguläre Ausdrücke für deine Anforderungen nicht mächtig genug sind.

Ich weiß zumindest, dass wir in unserer Software ähnliche Komplexitätsanforderungen haben und die nicht mittels regex erschlagen (können).
 
Zuletzt bearbeitet:
dafuer benutzt man kein regex.*

e: * zumindest nicht ein einziges.

maechtig genug ist die sprache fuer die anforderungen wahrscheinlich schon, aber das ist dann so'n fall wo dein pattern in sachen laenge zwischen einem absatz und einer seite rauskommt und deutlich unleserlicher als wenn man einfach eine validierungsfunktion schreibt... du brauchst fuer eine sinnvolle loesung sicherlich mehrere untersuchungen. naja, fangen wir mal an.

- Mindestens 8 Zeichen
str.length() >= 8
- Maximal 5 mal gleiches Zeichen im gesamten String
das ist in meinen augen 'ne voellig bescheuerte vorgabe, aber da wuerde ich mir einfach ne character-basierte helferfunktion schreiben und sicher stellen, dass die eingaben auf irgendein maximum limitiert sind (worst case zeit-/speicherkomplexitaet O(n))
- Mind. 3 unterschiedliche Zeichengruppen sollen Verwendung finden aus diesen 4:
- - Kleinbuchstaben
- - Großbuchstaben
- - Sonderzeichen (deutsche Tastatur)
- - Ziffern
machste vier patterns mit je 'ner character group (vergleiche hier): "[\p{L}&&[^\p{Lu}]]", "\p{Lu}", "[^\p{IsAlphabetic}]" (wobei das vmtl. auch zahlen faengt), "\d".
auf diese vier patterns testest du jeweils, und wenn Matcher.find() wahr ist inkrementierste 'nen int, wenn der am ende >= 3 ist ist alles okay.
 
Zuletzt bearbeitet:
Nach meinem Kenntnisstand (und ich würde sagen ich hab schon so durchaus einiges mit regulären Ausdrücken gemacht) sind außer der ersten Anforderung (mindestens 8 Zeichen) keine der genannten Anforderungen mit Regular Expressions umsetzbar bzw sinnvoll umsetzbar.
Kann sein dass man das mit den verschiedenen Zeichengruppen zumindest irgendwie FORMULIEREN kann, aber ich glaube das dabei entstehende Pattern wäre ziemlich eklig. Das will man so auch nicht machen..
 
Die nice-to-have-Bedingung könnte man mit einer Helper-Funktion lösen, die zurückgibt, ob 2 Zeichen auf der Tastatur nebeneinander liegen. Dann den String paarweise durchgehen und Counter inkrementieren/zurücksetzen.
Aber:
Praktisch würde ich solche restriktiven Regeln nicht forcieren. Denn: es sind weiterhin unsichere Passwörter aus Wortlisten möglich (z.B. "Passw0rt" müsste diesem Regelsatz genügen und in Dutzend Listen stehen) und lange, vermutlich sichere Passwörter könnten gegen eine der Regeln verstoßen. Ich habe da so einige unschöne Erfahrungen gemacht mit meinem Passwort-Generator und zufälligen 16+ Strings. Wenn das nicht auf Anhieb klappt da herauszufinden woran es hängt... :pcangry:
Je länger das Passwort, desto wahrscheinlicher dass 5 mal das selbe Zeichen vorkommt, und je unwichtiger werden verschiedene Zeichengruppen. Länge ist wichtiger als Anzahl der Zeichen.
Schöner finde ich hingegen, das vom Nutzer eingegebene Passwort zu bewerten, farblich gestützt, und ihn so zur Eingabe eines sicheren Passworts zu bewegen und die Länge als einziges Kriterium vorzugeben.
 
AnonStar schrieb:
Ich möchte einen Passwortvalidator mittels regex (in Java mit @Pattern beim Mappen auf's Modell) realisieren.
Das Problem ist nicht neu - einmal eine Suchmaschine angeworfen brachte den folgenden Link:
http://stackoverflow.com/questions/19605150/regex-for-password-must-be-contain-at-least-8-characters-least-1-number-and-bot
Da sind bis auf Deinen optionalen Wunsch und die Zeichenwiederholungen alle Fälle abgehandelt.

Deine Prüfung auf Zeichenwiederholung ist mit regex zwar machbar, aber Du müsstest für jedes zulässige Zeichen prüfen, ob dieses 5 mal vorkommt. Auch ist das gerade wenn jemand ein längeres Passwort wählt ziemlich sinnfrei. Gleiches gilt für die Prüfung auf nebeneinanderliegende Tasten.
 
Zuletzt bearbeitet: (Rechtschreibung korrigiert)
- Maximal 4 nebeneinanderliegende Zeichen (deutsche Tastatur) (bspw: [qwer] ist ok, [qwert] wird abgelehnt)
wer denkt sich denn sowas aus? :)

Code:
String pass = "foobarASdfgfoobar";

int maxLen = 4;

String[] keyboard = new String[] {
	"qwertzuiopü+",
	"asdfghjklöä'",
	"yxcvbnm,.-"
};

for(String kbLine : keyboard) {
	for(int offset = 0; offset <= kbLine.length() - maxLen - 1; offset++) {
		String sequence = kbLine.substring(offset, offset + maxLen + 1);
		if(pass.toLowerCase().indexOf(sequence) != -1) {
			System.err.println("sequence " + sequence + " found, password invalid");
		}
		offset++;
	}
}
 
Hey,

vielen Dank für die vielen Antworten. Ich beantworte mal die Frage nicht, woher ich diese Vorgaben bekommen habe ^^
Es ist im Endeffekt wohl wirklich nicht so schön mit regex. Zum Glück habe ich jars bei uns gefunden, die Regel 2 und 4 abdecken (nebeneinanderliegende Zeichen und Zeichenwiederholung).

Mit regex habe ich jetzt nur Regel 1 und 3 gelöst, und zwar so:

Code:
((?=.*[a-zA-Z])(?=.*\d)(?=.*[\^°!“"§$%&/()=?`²³{\[\]}<>|@€µ,;.:\-_#’+\*~])|(?=.*[a-z\d])(?=.*[A-Z])(?=.*[\^°!“"§$%&/()=?`²³{\[\]}<>|@€µ,;.:\-_#’+\*~])|(?=.*[a-z])(?=.*[A-Z])(?=.*\d)).{8,}

Grüße,

Anon
 
AnonStar schrieb:
ich arbeite hin-und-wieder mit regular expressions, das ist aber jetzt schon so lange her, dass ich das gar nicht mehr kann. Und einfach fand ich das noch nie.
Ja. Schwer ist es nicht und es gibt auch Online-RegEx-Tester, wo man mal ein bisschen herumspielen kann. Allerdings sind RegExp auch schwer zu lesen und ggf. zu debuggen, sobald sie etwas länger sind.



AnonStar schrieb:
Ich möchte einen Passwortvalidator mittels regex (in Java mit @Pattern beim Mappen auf's Modell) realisieren.
Ich möchte mit dem regex gegen die folgende Passwortrichtlinie validieren:
Sollst Du alles mit RegExp realisieren und wenn ja nur mit einer oder mit mehreren?

AnonStar schrieb:
- Mindestens 8 Zeichen
Trivial. Besonders wenn man keine RegExp verwenden muss.

AnonStar schrieb:
- Maximal 5 mal gleiches Zeichen im gesamten String
Würde ich bevorzugt ohne RegExp lösen.

AnonStar schrieb:
- Mind. 3 unterschiedliche Zeichengruppen sollen Verwendung finden aus diesen 4:
Hier RegExp als Hilfsmittel ok. Würde mich aber davor hüten irgendein Monster-RegExp aufzubauen, da kaum lesbar.

AnonStar schrieb:
nice to have:
- Maximal 4 nebeneinanderliegende Zeichen (deutsche Tastatur) (bspw: [qwer] ist ok, [qwert] wird abgelehnt)
Nicht wirklich problematisch. Aber Frage auch hier wieder, ob sich dafür ne RegExp lohnt.
 
AnonStar schrieb:
Mit regex habe ich jetzt nur Regel 1 und 3 gelöst, und zwar so:

Code:
((?=.*[a-zA-Z])(?=.*\d)(?=.*[\^°!“"§$%&/()=?`²³{\[\]}<>|@€µ,;.:\-_#’+\*~])|(?=.*[a-z\d])(?=.*[A-Z])(?=.*[\^°!“"§$%&/()=?`²³{\[\]}<>|@€µ,;.:\-_#’+\*~])|(?=.*[a-z])(?=.*[A-Z])(?=.*\d)).{8,}

Grüße,

Anon

Das wäre mir schon zu unübersichtlich und nicht mehr wartbar. Du oder deine Mitarbeiter werden dich dafür verfluchen, wenn sie da irgendwann nochmal ranmüssen. :P
 
mental.dIseASe schrieb:
Das wäre mir schon zu unübersichtlich und nicht mehr wartbar.
Schon allein die Frage zu klären, ist das jetzt eine RegExp, ein Perl-Skript oder ist einfach nur ne Katze über die Tastatur gelaufen. :)
 
Ihr immer mit eurem Gemecker :p

Ist natürlich darüber im Kommentar erläutert =)

Code:
    /*
     * RegEx-Pattern:
     * ((?=.*[a-zA-Z])(?=.*\d)(?=.*[\^°!“\"§$%&\/()=?`²³{\[\]}<>|@€µ,;.:\-_#’+\*~])|
     * (?=.*[a-z\d])(?=.*[A-Z])(?=.*[\^°!“\"§$%&\/()=?`²³{\[\]}<>|@€µ,;.:\-_#’+\*~])|
     * (?=.*[a-z])(?=.*[A-Z])(?=.*\d))
     * .{8,} 
     * 
     * This RegEx is using positive lookahead.
     *
     * 1st group:
     * (?=.*[a-zA-Z])(?=.*\d)(?=.*[\^°!“\"§$%&\/()=?`²³{\[\]}<>|@€µ,;.:\-_#’+\*~])
     * In String exists at least one character: (?=.*[a-zA-Z])
     * AND at least one digit: (?=.*\d)
     * AND at least one symbol in ^°!“"§$%&/()=?`²³{[]}<>|@€µ,;.:-_#’+*~
     * 
     * OR 2nd group:
     * (?=.*[a-z\d])(?=.*[A-Z])(?=.*[\^°!“\"§$%&\/()=?`²³{\[\]}<>|@€µ,;.:\-_#’+\*~])
     * In String exists at least one lower case character or digit: (?=.*[a-z\d])
     * AND at least one upper case character: (?=.*[A-Z])
     * AND at least one symbol in ^°!“"§$%&/()=?`²³{[]}<>|@€µ,;.:-_#’+*~
     * 
     * OR 3rd group:
     * (?=.*[a-z])(?=.*[A-Z])(?=.*\d)
     * In String exists at least one lower case character: (?=.*[a-z])
     * AND at least one upper case character: (?=.*[A-Z])
     * AND at least one digit: (?=.*\d)
     * 
     * The whole String has a minimum length of 8 by matching the groups: .{8,}
     * 
     */
  private static String PASSWORD_PATTERN = "((?=.*[a-zA-Z])(?=.*\\d)(?=.*[\\^°!“\"§$%&\\/()=?`²³{\\[\\]}<>|@€µ,;.:\\-_#’+\\*~])|(?=.*[a-z\\d])(?=.*[A-Z])(?=.*[\\^°!“\"§$%&\\/()=?`²³{\\[\\]}<>|@€µ,;.:\\-_#’+\\*~])|(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)).{8,}";
 
Zuletzt bearbeitet:
Zurück
Oben