PowerShell – 13 – Simpler Passwortgenerator

Ich habe mir einen einfachen Passwortgenerator mit PowerShell gebastelt. Gut, einfach nur ein Passwort generieren mit Get-Random ist relativ einfach. Doch ich wollte noch ein wenig mehr. Ich möchte bestimmen wie groß der Anteil (prozentual) von Großbuchstaben, Kleinbuchstaben, Nummern sowie Sonderzeichen ist. Soweit zur Idee.

Was habe ich im Script genutzt

Für dieses Script habe ich mehrere bereits beschriebene Elemente genutzt. Der Generator basiert auf der Funktion Get-Random, welche ich im Artikel PowerShell – 02 – Random beschrieben habe. Selbst einen Zufallsalgorithmus zu entwickeln ist hoch komplex und erfordert ebenfalls etwas mehr Zeit. Im Script setze mehrfach Get-Random ein um die zufällige Erstellung des Passwortes zu maximieren. Weiterhin habe ich die Switch- oder auch Case-Schleife verwendet. Diese habe ich im Artikel PowerShell – 11.1 – Logfiles mit einer Function erstellen näher beschrieben. Hier prüfe ich allerdings keine Worte/Zeichen sondern numerische Werte. Weiterhin lasse ich die benötigte Zeit ermitteln welche zur Erstellung des Passwortes benötigt wird. Dies kann entweder mit Measure-Command (PowerShell – Scriptdauer messen Teil 2) oder mit einer selbstgeschrieben Variante (PowerShell – Scriptdauer messen Teil 1) gemessen werden. Ich habe mich im Script für meine selbst erstellte Variante entschieden. Zu guter Letzt nutzet ich die Funktion Runden (Round) aus der Mathematikbibliothek (Math).

Input des Scriptes

Im Script müssen mehrere Variablen angeben werden. Diese habe ich in der folgenden Tabelle näher beschrieben.

Name Typ Beschreibung
$PWDLength Int32 Diese Variable legt die Länge des Passwortes fest. Definiert ist sie als Int32 damit auch besonders lange Passwörter möglich sind (bis zu 2.147.483.647 Zeichen).
$AmountABC_percent Int Diese Variable legt den prozentualen Wert der Großbuchstaben (A-Z) fest. Dieser Wert kann von 0 bis 100 gesetzt werden. Wobei Gesamtsummer aller $Amount* Variablen nicht über 100 sein darf.
$AmountABCsm_percent Int Diese Variable legt den prozentualen Wert der Kleinbuchstaben fest (a-z). Dieser Wert kann von 0 bis 100 gesetzt werden. Wobei Gesamtsummer aller $Amount* Variablen nicht über 100 sein darf.
$AmountNR_percent Int Diese Variable legt den prozentualen Wert der Ziffern(0-9) fest. Dieser Wert kann von 0 bis 100 gesetzt werden. Wobei Gesamtsummer aller $Amount* Variablen nicht über 100 sein darf.
$AmountSign_percent Int Diese Variable legt den prozentualen Wert der Sonderzeichen ($,!,%,^) fest. Dieser Wert kann von 0 bis 100 gesetzt werden. Wobei Gesamtsummer aller $Amount* Variablen nicht über 100 sein darf.
$AllAmounts_percent Int

Diese Variable fast alle $Amount* Variablen zusammen. Anschließend wird geprüft, ob diese größer gleich 100 ist. Ist sie größer als 100 wird ein Fehler ausgegeben mit dem Hinweis das die Werte angepasst werden müssen. Ist diese Variable kleiner 100 wird der Wert von $AmountABC_percent solange um jeweils 1 erhöht bis der Wert von $AllAmounts_percent 100 entspricht.

Funktionsweise des Scriptes

Nachdem die oben genannten Werte angeben sind geht es im Script wie folgt weiter. Es wird zu erst geprüft, ob die Variable $AllAmounts_percent  kleiner 100 ist. Trifft dies zu, wird der Wert der Variable $AmountABC_percent (Anzahl Großbuchstaben) jeweils um eins erhöht bis $AllAmounts_percent gleich 100 ist. Übersteigt $AllAmounts_percent jedoch den Wert 100 bricht das Script mit der Fehlermeldung „Prozentuale Werte sind über 100%!“ ab. Ausgelöst durch break.

Im nächsten Schritt werden vier Arrays ($Chars_*) initiiert für Groß- und Kleinbuchstaben, Ziffern sowie für Sonderzeichen. Diese können beliebig erweitert werden.

Nun wird eine als String deklarierte Variable $UserPassword angelegt. Die Variable wird im folgenden Switch-Statement verwendet. Dazu muss sie vorher bereits existieren. Inhalt der Variable ist am Ende das generierte Passwort.

Es werden zwei weitere Arrays gebildet, $AllAmounts_array und $AllAmountsArray. Das Array $AllAmounts_array enthält alle vier Werte der $Amount* Variablen. $AllAmountsArray wird zunächst nur initiiert. Dieses wird für die folgende For-Schleife benötigt.

In der folgenden For-Schleife kommt die Round Funktion der Math Bibliothek zum Einsatz. Hier breche ich die angegebenen prozentualen Werte auf Ganzahlen (integer) herunter. Dazu nehme ich die Länge des Passwortes geteilt durch 100. Das Ergebnis wird anschließend mit dem Wert von $AllAmounts_array[$i] multipliziert. $i entspricht jeweils dem Wert von $AmountABC_percent, $AmountABCsm_percent, $AmountNR_percent oder $AmountSign_percent.

Die gesamt ermittelten Werte von $AllAmountsArray werden auf die entsprechenden $Amount*_numeric Variablen verteilt. Es kann sein das die Gesamtsumme nicht 100 erreicht. Dies kommt durch das Runden der Prozentangaben.

In der folgenden If-Schleife wir der Wert von $AllAmounts geprüft. Ist dieser nicht 100 wird auch hier wieder der Anteil von Großbuchstaben ($AmountABC_numeric) erhöht. Somit ist gewehrleistet, das die Passwortlänge in jedem Fall erreicht wird.

Nach diesen ganzem Vorgeplänkel kommt nun der eigentliche und spannende Teil, das Zusammenstellen des Passwortes. In der Do-While-Schleife wird erst eine Wert zwischen 0 und 3 mittels Get-Random ausgewürfelt (Daran denken, dass Null auch eine Zahl ist). Die „zufällig“ generiete Zahl spring dran in einen der vier Cases. Diese habe ich in der Tabelle kurz beschrieben.

Case Was passiert
0 Es wird ein Großbuchstabe dem Passwort ($UserPassword) hinzugefügt
1 Es wird ein Kleinbuchstabe dem Passwort ($UserPassword) hinzugefügt
2 Es wird eine Ziffer dem Passwort ($UserPassword) hinzugefügt
3 Es wird ein Sonderzeichen dem Passwort ($UserPassword) hinzugefügt

Was passiert nun genau in diesem Case?  In Case 0 wird geprüft, ob der Wert von $AmountABC_numeric gleich null ist. Ist der Wert der Variable nicht null wird dieser innerhalb der If-Bedingung um eins verringert und die Variable $UserPassword wird um ein Zeichen erweitert. Hierzu wird ein Wert des Array $Chars_ABC mittels Get-Random ausgewählt. Das Maximum bei Get-Random habe ich mit $Chars_ABC.Count festgelegt. So beleibt das Script dynamisch, da z.B. das Array $Chars_Sign um weitere Sonderzeichen erweitert werden kann. Die Do-While-Schleife wird solange ausgeführt bis die Länge von $UserPassword mit der gewünschten Länge ($PWDLength) übereinstimmt. Tritt dieser Fall ein, sind alle $Amount*_numeric Variablen gleich null. Der ganze Vorgang ist analog für die anderen Cases 1-3 zu betrachten.

Hinweis zu Get-Random:
Bei Get-Random muss das Minimum nicht zwingend angegeben werden, wenn es Null ist/ sein soll. Dennoch habe ich es bei den anderen Get-Randoms angegeben. Dies wäre aber nicht nötig.

Anschließend folgt nur noch der Output. Hier wird zu erst das Passwort angezeigt, gefolgt von der Länge des Passwortes. Darunter wird noch die benötigte Zeit angeben die das Script gebraucht hat. Fertig 🙂

Weitere Features

Das Script werde ich noch als Funktion umschreiben damit die Angabe der Werte einfacher von der Hand gehen. Zudem möchte ich das Script mit einer GUI verstehen und als umgewandelte ausführbare Datei (EXE) erstellen. Sodass ein einfache Starten als Tool möglich ist. Diesen Vorgang werde ich natürlich auch hier wieder detailliert beschreiben.

Eines der größeren Schritte soll dann die Aufnahme in ein selbst erstelltes Modul werden. Das Modul soll dann mehrere praktische Scripte enthalten und stets erweitert werden. Hierzu werde ich dann eine eigene Reihe von Artikeln auf meinem Blog verfassen.

Das komplette Script

Hier nun das Script in seiner vollen Länge mit Header und Versionsverwaltung. Beispielausgaben des Scriptes stehen darunter.

Ausgabe des Script

Mit steigender Länge des Passwortes benötigt das Script entsprechend mehr Zeit. Das Script lässt sich garantiert noch etwas performanter gestalten, aber ich denke für ein Passwort mit 100 Stellen sind 75 ms ganz in Ordnung.Aus optischen Gründen habe ich die Passwörter in der Ausgabe als String in Kochkommas gestellt. Dieser werden in der normalen Ausgabe nicht angezeigt.

 

Viele Grüße

rewe

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert