Generieren eines zufälligen Passworts in PHP

190

Ich versuche ein zufälliges Passwort in PHP zu generieren.

Ich bekomme jedoch alle 'a' und der Rückgabetyp ist vom Typ Array und ich möchte, dass es ein String ist. Irgendwelche Ideen, wie man den Code korrigiert?

Vielen Dank.

function randomPassword() {
    $alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
    for ($i = 0; $i < 8; $i++) {
        $n = rand(0, count($alphabet)-1);
        $pass[$i] = $alphabet[$n];
    }
    return $pass;
}
Nunos
quelle
9
Keine der Antworten verwendet einen sicheren Zufallszahlengenerator , den Sie für ein Passwort benötigen.
Scott Arciszewski
4
Besucher sollten potenziell sicherheitsrelevante Informationen aus einer Quelle erhalten, die ordnungsgemäß aktualisiert werden kann, und keine Frage, die für neue Antworten geschlossen ist. Ich lösche die Antworten auf dieses Duplikat, damit die Besucher stattdessen die Antworten auf die offene Frage lesen. (Wenn diese Frage jemals wieder geöffnet wird, werden die Antworten nicht gelöscht.)
Jeremy Banks
6
@JeremyBanks Nirgendwo in der Frage heißt es, dass ein kryptografisch sicheres Passwort erforderlich ist. Für einige Leute sind die Antworten /dev/randomausreichend, da die Frage nicht nach einem " sicheren " Passwort fragt (und nicht so bearbeitet werden sollte, dass es die Bedeutung der ursprünglichen Frage ändert). Obwohl ich alles für die Sicherheit bin, denke ich, dass diese Teppichbombe nicht vollständig durchdacht war. Wie bei der Verwendung mysql_*sind die Antworten weiterhin gültig, sollten jedoch als unsicher markiert werden. Vielleicht ist dies etwas, das SO als zusätzliche Software einbinden muss - die Fähigkeit, vor unsicherem Code zu warnen ?
Jimbo
6
@JeremyBanks Können Sie bitte die Antworten auf diese Frage wieder herstellen? Nur weil es sich um ein Duplikat handelt, bedeutet dies nicht, dass die Antworten falsch sind (ich habe versehentlich für die Wiedereröffnung gestimmt, ich stimme zu, dass es sich um ein Duplikat handelt). Es macht keinen Sinn, die Antworten zu löschen. Entfernen Sie stattdessen diese Frage und migrieren Sie die Antworten auf die andere Frage (ich habe es schon einmal gesehen).
Naftali aka Neal
7
@JeremyBanks Wenn Sie möchten, dass etwas nicht wieder geöffnet wird, sperren Sie es. Andernfalls öffnen 99% der Benutzer es erneut und verursachen ein ganzes Durcheinander. Persönlich bin ich überhaupt nicht damit einverstanden, hoch bewertete Antworten einfach so zu löschen, kann mich aber nicht
Shadow Wizard ist Ear For You

Antworten:

258

Sicherheitswarnung : rand()ist kein kryptografisch sicherer Pseudozufallszahlengenerator. Suchen Sie an anderer Stelle nach einer kryptografisch sicheren Pseudozufallszeichenfolge in PHP .

Versuchen Sie dies (verwenden Sie strlenstatt count, weil countauf einer Zeichenfolge immer steht 1):

function randomPassword() {
    $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
    $pass = array(); //remember to declare $pass as an array
    $alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
    for ($i = 0; $i < 8; $i++) {
        $n = rand(0, $alphaLength);
        $pass[] = $alphabet[$n];
    }
    return implode($pass); //turn the array into a string
}

Demo: http://codepad.org/UL8k4aYK

Neal
quelle
24
Scheint einfacher zu bedienen $pass .= $alphabet[$n].
Matthew
33
Das Generieren eines Passworts mit Rand ist eine wirklich schlechte Idee. Es ist kein sicheres PRNG. (und nein mt_randist auch nicht besser)
CodesInChaos
19
Die Frage ist über das Generieren eines Passworts . Code zum Generieren eines Passworts muss eindeutig sichere Zufallszahlen verwenden.
CodesInChaos
10
Aus dem gleichen Grunde wie das ist nicht eine doppelte Frage, ist diese Antwort falsch, da die Frage nach ist ein Passwort zu erzeugen und nicht eine zufällige Zeichenfolge . Diese Antwort bietet einen schrecklich unsicheren Ansatz zum Generieren eines Passworts. Bitte verwenden Sie die Antwort von @ user3260409 unten, wo openssl_random_pseudo_bytes()anstelle vonrand()
Sorry-Im-a-N00b
35
Ich habe Ihren unsicheren Code in der Produktion gesehen und möchte ihn an der Quelle stoppen. Sie MÜSSEN kryptografisch sichere Zufälligkeiten für Passwörter.
Scott Arciszewski
120

TL; DR:

  • Verwenden Sie random_int()und die random_str()unten angegebenen.
  • Wenn nicht random_int(), verwenden Sie random_compat .

Erläuterung:

Da Sie ein Kennwort generieren , müssen Sie sicherstellen, dass das von Ihnen generierte Kennwort nicht vorhersehbar ist. Die einzige Möglichkeit, um sicherzustellen, dass diese Eigenschaft in Ihrer Implementierung vorhanden ist, besteht in der Verwendung eines kryptografisch sicheren Pseudozufallszahlengenerators (CSPRNG).

Die Anforderung für ein CSPRNG kann für den allgemeinen Fall von zufälligen Zeichenfolgen gelockert werden, jedoch nicht, wenn es um Sicherheit geht.

Die einfache, sichere und korrekte Antwort auf die Kennwortgenerierung in PHP besteht darin, RandomLib zu verwenden und das Rad nicht neu zu erfinden. Diese Bibliothek wurde sowohl von Sicherheitsexperten der Branche als auch von mir geprüft.

Für Entwickler, die es vorziehen, Ihre eigene Lösung zu erfinden, bietet PHP 7.0.0 random_int()diesen Zweck. Wenn Sie noch mit PHP 5.x arbeiten, haben wir eine PHP 5-Polyfüllung für geschrieben,random_int() damit Sie die neue API verwenden können, bevor PHP 7 veröffentlicht wird. Die Verwendung unserer random_int()Polyfüllung ist wahrscheinlich sicherer als das Schreiben einer eigenen Implementierung.

Mit einem sicheren Generator für zufällige Ganzzahlen ist das Generieren einer sicheren Zufallszeichenfolge einfacher als Kuchen:

<?php
/**
 * Generate a random string, using a cryptographically secure 
 * pseudorandom number generator (random_int)
 * 
 * For PHP 7, random_int is a PHP core function
 * For PHP 5.x, depends on https://github.com/paragonie/random_compat
 * 
 * @param int $length      How many characters do we want?
 * @param string $keyspace A string of all possible characters
 *                         to select from
 * @return string
 */
function random_str(
    $length,
    $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
) {
    $str = '';
    $max = mb_strlen($keyspace, '8bit') - 1;
    if ($max < 1) {
        throw new Exception('$keyspace must be at least two characters long');
    }
    for ($i = 0; $i < $length; ++$i) {
        $str .= $keyspace[random_int(0, $max)];
    }
    return $str;
}
Scott Arciszewski
quelle
2
RandomLib wurde seit über zwei Jahren nicht mehr aktualisiert. Wenn Sie es in einem aktuellen PHP-Build (in meinem Fall 7.1.25) verwenden, werden für verschiedene mcrypt_*Funktionen Verfallswarnungen ausgegeben . Ich kann in einem Problem-Thread sehen, dass Sie die Bibliothek gegabelt haben, weil Sie @ircmaxell nicht erreichen können, aber in Ihrer Verzweigung steht "Build Failing" für Travis. Möchten Sie diese Antwort aktualisieren (die bei Google immer noch recht häufig angezeigt wird)?
Janus Bahs Jacquet
1
Guter Fang! Es muss entfernt werden.
Scott Arciszewski
113

Ich weiß, dass Sie versuchen, Ihr Passwort auf eine bestimmte Weise zu generieren, aber vielleicht möchten Sie sich auch diese Methode ansehen ...

$bytes = openssl_random_pseudo_bytes(2);

$pwd = bin2hex($bytes);

Es stammt von der php.net-Site und erstellt eine Zeichenfolge, die doppelt so lang ist wie die Zahl, die Sie in die Funktion openssl_random_pseudo_bytes eingegeben haben. Das obige würde also ein 4 Zeichen langes Passwort erstellen.

Zusamenfassend...

$pwd = bin2hex(openssl_random_pseudo_bytes(4));

Würde ein Passwort mit 8 Zeichen Länge erstellen.

Beachten Sie jedoch, dass das Passwort nur die Zahlen 0-9 und Kleinbuchstaben af ​​enthält!

user3260409
quelle
13
Wenn Sie ein Passwort in Groß- und Kleinbuchstaben und Zahlen wünschen
Folgendes
@ زياد Sagt wer? Wenn der Generator 7-Bit-Bytes verwenden würde, würde ich Ihnen zustimmen, ist aber openssl_random_pseudo_bytes()ein leistungsstarker Zufallsgenerator für vollständige binäre Bytes und muss nicht weiter gemischt werden. Ich werde auch die Gelegenheit nutzen, um darauf hinzuweisen, dass es gefährlich ist anzunehmen, dass das Stapeln mehrerer Verschlüsselungsmethoden alles zufälliger macht. In einigen Fällen kann es aufgrund der akkumulierten Hashing-Kollisionen sogar genau umgekehrt sein.
Havenard
56

Winziger Code mit 2 Zeilen.

Demo: http://codepad.org/5rHMHwnH

function rand_string( $length ) {

    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    return substr(str_shuffle($chars),0,$length);

}

echo rand_string(8);

Mit rand_string können Sie festlegen, wie viel Zeichen erstellt werden sollen.

BSQ
quelle
21
Schön, obwohl Sie mit diesem Ansatz keine wiederholten Zeichen erhalten, was möglicherweise unerwünscht ist.
Hobo
11
Diese Funktion ist schrecklich, um lange Passwörter zu generieren. Wenn $ length länger als die Zeichenfolge $ chars ist, erhalten Sie zunächst keine Zeichenfolge, die so lang ist wie die von Ihnen eingegebene Länge, sondern die Länge der Zeichenfolge. Außerdem wird Ihnen garantiert nur 1 von jedem Zeichen ohne Duplikate garantiert. Es garantiert auch nicht die Verwendung eines Großbuchstabens oder einer Zahl, was häufig erforderlich ist (außer natürlich, wenn Ihre Länge aufgrund des vorherigen Fehlers mehr als 26 beträgt)
Programster
Was ist mit diesem @Programster und @Hobo? substr(str_shuffle(str_repeat($chars,$length)),0,$length);
Charles-Édouard Coste
@ Charles-EdouardCoste scheint in Ordnung zu sein (besonders wenn Sie einige spezielle Zeichen einwerfen). Obwohl es immer noch nicht mindestens einen von jedem Zeichentyp garantiert . Das einzige, was mich stört, ist die Wiederholung des gesamten Zeichensatzes um die Länge des gewünschten Passworts, aber dies stellt sicher, dass die Zeichen im generierten Passwort nicht eindeutig sein müssen und bei einer einmaligen Verwendung keine spürbaren Auswirkungen auf die Leistung haben.
Programster
Ich stimme zu. Es ist wahrscheinlich besser, keinen Algorithmus für die Anzahl der Zeilen zu wählen. Übrigens, wenn das Hauptziel darin besteht, beim Erstellen eines neuen Benutzers auf einer Website nur ein temporäres Passwort zu generieren, würde dies die Anforderungen erfüllen, denke ich.
Charles-Édouard Coste
40

Wenn Sie mit PHP7 arbeiten, können Sie folgende random_int()Funktion verwenden:

function generate_password($length = 20){
  $chars =  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
            '0123456789`-=~!@#$%^&*()_+,./<>?;:[]{}\|';

  $str = '';
  $max = strlen($chars) - 1;

  for ($i=0; $i < $length; $i++)
    $str .= $chars[random_int(0, $max)];

  return $str;
}

Alte Antwort unten:

function generate_password($length = 20){
  $chars =  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
            '0123456789`-=~!@#$%^&*()_+,./<>?;:[]{}\|';

  $str = '';
  $max = strlen($chars) - 1;

  for ($i=0; $i < $length; $i++)
    $str .= $chars[mt_rand(0, $max)];

  return $str;
}
PeeHaa
quelle
12
Verwenden Sie nicht mt_rand, um ein Passwort zu generieren.
CodesInChaos
2
@CodesInChaos ist besser als rand (), was im obigen Beispiel verwendet wird. openssl_random_pseudo_bytes () wird laut PHP-Handbuch bevorzugt.
Willbradley
4
@willbradley Die Qualität des Saatguts ist genauso schlecht mt_rand, daher ist es für Sicherheitszwecke immer noch ungeeignet.
CodesInChaos
2
Sie sehen, das nervt mich + ChaosInCodes. Sie haben sich die Frage nicht angesehen, sondern nur einige allgemeine Aussagen gemacht, die eine Menge schlecht gehaltener Überzeugungen wiederholen. Kurzum: richtiger Ratschlag für eine ganz andere Frage. Zufällige Passwörter sind in Ordnung. Sie werden wahrscheinlich nur "x" verwendet. Ganz ehrlich, wenn Sie Ihr System ohne zeitgesteuerte Sperren und DOS-Erkennung entwerfen und "x versucht dann -> gesperrt", dann machen Sie es falsch. Es ist UNMÖGLICH, ein mt_rand-Passwort mit solchen Maßnahmen zu erraten. Umgekehrt macht es die Verwendung von mt_rand nicht einfacher, ein Passwort brutal zu erzwingen. Es wird einfach nicht.
Herr Heelis
1
Ich würde \ in$chars
CONvid19
36

In einer Zeile:

substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') , 0 , 10 )
Sandra
quelle
11
Dies verhindert, dass dieselben Buchstaben wiederverwendet werden, wenn sie nur gemischt werden, aber nicht mehr als einmal vorkommen.
Nickdnk
8
Es ist unnötig zu erwähnen, dass niemand seine Passwortgenerierungsfunktion basierend auf der Zeilenanzahl optimieren sollte. Selbst wenn das verwendete RNG sicher war (nicht), werden Sie durch das Vermeiden wiederholter Zeichen beim Generieren eines 10-stelligen Passworts von ~ 52 Bit Entropie auf ~ 50 Bit Entropie (~ 4x schneller zu knacken) gesenkt. Wenn Sie dies auf 20 Zeichen erweitern würden, würde die Nichtwiederholung Sie von ~ 103 Bit auf ~ 94 Bit senken (~ 512x schneller zu knacken).
Jeremy Banks
1
Diese Methode erinnert mich an den Fehler im Enigma-Code Lol
hatef
4
substr(str_shuffle(str_repeat($chars,$length)),0,$length); Entropie wiederhergestellt
Charles-Édouard Coste
27

Ihre beste Wahl ist die RandomLib-Bibliothek von ircmaxell .

Anwendungsbeispiel:

$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new SecurityLib\Strength(SecurityLib\Strength::MEDIUM));

$passwordLength = 8; // Or more
$randomPassword = $generator->generateString($passwordLength);

Es werden Zeichenfolgen erzeugt, die stärker zufällig sind als die normalen Zufallsfunktionen wie shuffle()und rand()(was Sie im Allgemeinen für vertrauliche Informationen wie Passwörter, Salze und Schlüssel wünschen).

Madaras Geist
quelle
4
Dies ist die richtige Antwort. Verwenden Sie nicht rand()oder mt_rand().
Scott Arciszewski
1
Es ist vielleicht die sicherste Antwort (nicht sicher, wie sie verglichen wird random_bytes), aber das macht die randAntworten nicht falsch.
Cerbrus
8
@ Cerbrus: Sicher, diese Antwort gibt keine rand()falschen Antworten . Sie sind von sich aus falsch!
Deduplikator
14

Sie wollen strlen($alphabet)nicht countdie Konstante alphabet(äquivalent zu 'alphabet').

Dies randist jedoch keine geeignete Zufallsfunktion für diesen Zweck. Seine Ausgabe kann leicht vorhergesagt werden, da er implizit mit der aktuellen Zeit gesetzt wird. Darüber hinaus randist nicht kryptografisch sicher; es ist daher relativ einfach, seinen internen Zustand aus der Ausgabe zu bestimmen.

Lesen Sie stattdessen von /dev/urandom, um kryptografisch zufällige Daten zu erhalten.

Phihag
quelle
14

Ich werde eine Antwort posten, da einige der vorhandenen Antworten nahe beieinander liegen, aber eine der folgenden haben:

  • Ein kleinerer Zeichenraum als gewünscht, damit entweder das Brute-Forcing einfacher ist oder das Kennwort für dieselbe Entropie länger sein muss
  • ein RNG , das nicht als kryptografisch sicher gilt
  • eine Voraussetzung für eine Bibliothek von Drittanbietern, und ich dachte, es könnte interessant sein, zu zeigen, was nötig ist, um es selbst zu tun

Diese Antwort umgeht das count/strlenProblem, da die Sicherheit des generierten Passworts, zumindest IMHO, über Ihre Anreise hinausgeht. Ich gehe auch von PHP> 5.3.0 aus.

Lassen Sie uns das Problem in die Bestandteile aufteilen, die sind:

  1. Verwenden Sie eine sichere Zufallsquelle, um zufällige Daten zu erhalten
  2. Verwenden Sie diese Daten und stellen Sie sie als druckbare Zeichenfolge dar

Für den ersten Teil bietet PHP> 5.3.0 die Funktion openssl_random_pseudo_bytes. Beachten Sie, dass die meisten Systeme zwar einen kryptografisch starken Algorithmus verwenden, Sie dies jedoch überprüfen müssen, damit ein Wrapper verwendet wird:

/**
 * @param int $length
 */
function strong_random_bytes($length)
{
    $strong = false; // Flag for whether a strong algorithm was used
    $bytes = openssl_random_pseudo_bytes($length, $strong);

    if ( ! $strong)
    {
        // System did not use a cryptographically strong algorithm 
        throw new Exception('Strong algorithm not available for PRNG.');
    }        

    return $bytes;
}

Für den zweiten Teil verwenden wir, base64_encodeda es eine Byte-Zeichenfolge benötigt und eine Reihe von Zeichen erzeugt, deren Alphabet dem in der ursprünglichen Frage angegebenen sehr nahe kommt. Wenn wir nicht mit nichts ausmachte +, /und =Zeichen in der letzten Zeichenfolge erscheinen und wir ein Ergebnis zumindest wollen $nZeichen lang, könnten wir einfach nutzen:

base64_encode(strong_random_bytes(intval(ceil($n * 3 / 4))));

Der 3/4Faktor beruht auf der Tatsache, dass die Base64-Codierung zu einer Zeichenfolge führt, deren Länge mindestens ein Drittel größer ist als die Byte-Zeichenfolge. Das Ergebnis ist genau, $nwenn es ein Vielfaches von 4 und ansonsten bis zu 3 Zeichen länger ist. Da die zusätzlichen Zeichen überwiegend das Auffüllzeichen sind =, können wir es auf die gewünschte Länge kürzen , wenn wir aus irgendeinem Grund die Einschränkung hatten, dass das Kennwort eine exakte Länge hat. Dies liegt insbesondere daran, dass für ein bestimmtes $nKennwort alle Kennwörter mit der gleichen Anzahl enden würden, sodass ein Angreifer, der Zugriff auf ein Ergebniskennwort hatte, bis zu 2 Zeichen weniger erraten müsste.


Wenn wir für zusätzliche Gutschriften die genaue Spezifikation wie in der Frage des OP erfüllen wollten, müssten wir ein bisschen mehr Arbeit leisten. Ich werde hier auf den Ansatz der Basiskonvertierung verzichten und mich für einen schnellen und schmutzigen entscheiden. Beide müssen aufgrund des 62-Eintrags langen Alphabets ohnehin mehr Zufälligkeit erzeugen, als im Ergebnis verwendet wird.

Für die zusätzlichen Zeichen im Ergebnis können wir sie einfach aus der resultierenden Zeichenfolge verwerfen. Wenn wir mit 8 Bytes in unserer Byte-Zeichenfolge beginnen, sind bis zu 25% der base64-Zeichen diese "unerwünschten" Zeichen, sodass das einfache Verwerfen dieser Zeichen zu einer Zeichenfolge führt, die nicht kürzer als das gewünschte OP ist. Dann können wir es einfach abschneiden, um die genaue Länge zu erhalten:

$dirty_pass = base64_encode(strong_random_bytes(8)));
$pass = substr(str_replace(['/', '+', '='], ['', '', ''], $dirty_pass, 0, 8);

Wenn Sie längere Kennwörter generieren, macht das Auffüllzeichen =einen immer kleineren Anteil des Zwischenergebnisses aus, sodass Sie einen schlankeren Ansatz implementieren können, wenn das Entleeren des für das PRNG verwendeten Entropiepools ein Problem darstellt.

Jeteon
quelle
1
Danke für diesen Zusatz. Keine der vorhandenen Antworten stellte fest, dass openssl_random_pseudo_bytesdies zu einem schwachen Ergebnis führen könnte. Ich wusste nicht, dass das der Fall war.
Jeremy Banks
12

base_convert(uniqid('pass', true), 10, 36);

z.B. e0m6ngefmj4

BEARBEITEN

Wie ich in den Kommentaren erwähnt habe, bedeutet die Länge, dass Brute-Force-Angriffe besser dagegen wirken als Timing-Angriffe. Daher ist es nicht wirklich relevant, sich Gedanken darüber zu machen, "wie sicher der Zufallsgenerator war". Die Sicherheit, speziell für diesen Anwendungsfall, muss die Benutzerfreundlichkeit ergänzen, damit die oben genannte Lösung für das erforderliche Problem tatsächlich gut genug ist.

Nur für den Fall, dass Sie bei der Suche nach einem sicheren Zufallszeichenfolgengenerator (wie ich annehme, dass einige Leute auf den Antworten basieren) auf diese Antwort gestoßen sind, wie zum Beispiel das Generieren von Token, würde ein Generator solcher Codes folgendermaßen aussehen:

function base64urlEncode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function secureId($length = 32) {

    if (function_exists('openssl_random_pseudo_bytes')) {
        $bytes = openssl_random_pseudo_bytes($length);
        return rtrim(strtr(base64_encode($bytes), '+/', '0a'), '=');
    }
    else { // fallback to system bytes

        error_log("Missing support for openssl_random_pseudo_bytes");

        $pr_bits = '';

        $fp = @fopen('/dev/urandom', 'rb');
        if ($fp !== false) {
            $pr_bits .= @fread($fp, $length);
            @fclose($fp);
        }

        if (strlen($pr_bits) < $length) {
            error_log('unable to read /dev/urandom');
            throw new \Exception('unable to read /dev/urandom');
        }

        return base64urlEncode($pr_bits);
    }
}
srcspider
quelle
1
PS - dies ist PHP - verwendet nur \, um den globalen Namespace zu bezeichnen.
Bob Gregor
Nur dass uniqid nicht kryptografisch sicher ist. Verwenden Sie stattdessen rand (): base_convert (rand (78364164096, 2821109907455), 10, 36);
Benubird
7
@Benubird rand () ist laut PHP-Handbuch auch nicht kryptografisch sicher. Das Handbuch schlägt stattdessen openssl_random_pseudo_bytes () vor.
Willbradley
Für die meisten Anwendungsfälle, insbesondere wenn der Angreifer keinen Zugriff auf die genaue Uhrzeit hat, ist dies vollkommen in Ordnung und erzeugt ein schönes mehr oder weniger menschenfreundliches "temporäres" Passwort. Wenn wir dies auf das Äußerste bringen würden, wäre die Länge hier weitaus schwieriger als die Funktion, mit der die Zufallszahl generiert wurde.
srcspider
Ich habe ein Beispiel zum Generieren vollständig sicherer Zeichenfolgen für Interessenten hinzugefügt. Es wird jedoch dringend empfohlen, dies nicht zu verwenden, wenn temporäre Kennwörter für Benutzer generiert werden. Selbst bei Verwendung der sicheren Version bleibt das Längenproblem bestehen.
srcspider
9

Ein anderer (nur Linux)

function randompassword()
{
    $fp = fopen ("/dev/urandom", 'r');
    if (!$fp) { die ("Can't access /dev/urandom to get random data. Aborting."); }
    $random = fread ($fp, 1024); # 1024 bytes should be enough
    fclose ($fp);
    return trim (base64_encode ( md5 ($random, true)), "=");
}
Askarel
quelle
1
Das Lesen von 1024 Bytes zum Komprimieren in einen kryptografischen 128-Bit-Hash der Entropie ist etwas verschwenderisch. Außerdem fread()werden standardmäßig 8192 Byte gepuffert, sodass Sie immer so viele /dev/urandommit dem angegebenen Code lesen können . Dies funktioniert auch nicht unter Windows. Ein großes Lob für die Verwendung eines CSPRNG.
Scott Arciszewski
9

Ein bisschen schlauer sein:

function strand($length){
  if($length > 0)
    return chr(rand(33, 126)) . strand($length - 1);
}

Überprüfen Sie es hier .

Amir Fo
quelle
7

Verwenden Sie diesen einfachen Code, um ein Med-Strong-Passwort mit einer Länge von 12 zu generieren

$password_string = '!@#$%*&abcdefghijklmnpqrstuwxyzABCDEFGHJKLMNPQRSTUWXYZ23456789';
$password = substr(str_shuffle($password_string), 0, 12);
Pablo Martinez
quelle
Das ist eigentlich (sehr?) Falsch. Tatsächlich wird jedes Zeichen aus dem Alphabet nur einmal verwendet, wodurch der Platz aller möglichen Werte (die für das Knacken relevant sind) erheblich verkleinert wird.
Radoslav Bodo
6

Versuchen Sie dies mit Großbuchstaben, Kleinbuchstaben, Zahlen und Sonderzeichen

function generatePassword($_len) {

    $_alphaSmall = 'abcdefghijklmnopqrstuvwxyz';            // small letters
    $_alphaCaps  = strtoupper($_alphaSmall);                // CAPITAL LETTERS
    $_numerics   = '1234567890';                            // numerics
    $_specialChars = '`~!@#$%^&*()-_=+]}[{;:,<.>/?\'"\|';   // Special Characters

    $_container = $_alphaSmall.$_alphaCaps.$_numerics.$_specialChars;   // Contains all characters
    $password = '';         // will contain the desired pass

    for($i = 0; $i < $_len; $i++) {                                 // Loop till the length mentioned
        $_rand = rand(0, strlen($_container) - 1);                  // Get Randomized Length
        $password .= substr($_container, $_rand, 1);                // returns part of the string [ high tensile strength ;) ] 
    }

    return $password;       // Returns the generated Pass
}

Nehmen wir an, wir brauchen einen 10-stelligen Pass

echo generatePassword(10);  

Beispielausgabe (n):

, IZCQ_IV \ 7

@wlqsfhT (d

1! 8 + 1 \ 4 @ uD

Sanjeev
quelle
Die randFunktion ist nicht wirklich kryptografisch sicher, so dass es ein ziemliches Risiko sein kann, ein Passwort damit zu generieren
Jeteon
3

Schneller. Einfaches, sauberes und konsistentes Format, wenn Sie dies wünschen

$pw = chr(mt_rand(97,122)).mt_rand(0,9).chr(mt_rand(97,122)).mt_rand(10,99).chr(mt_rand(97,122)).mt_rand(100,999);
Cornelius Parkin
quelle
3

Dies basiert auf einer anderen Antwort auf dieser Seite, https://stackoverflow.com/a/21498316/525649

Diese Antwort erzeugt nur Hex-Zeichen 0-9,a-f. Versuchen Sie Folgendes für etwas, das nicht wie Hex aussieht:

str_shuffle(
  rtrim(
    base64_encode(bin2hex(openssl_random_pseudo_bytes(5))),
    '='
  ). 
  strtoupper(bin2hex(openssl_random_pseudo_bytes(7))).
  bin2hex(openssl_random_pseudo_bytes(13))
)
  • base64_encode Gibt eine größere Verbreitung alphanumerischer Zeichen zurück
  • rtrimentfernt das =manchmal am ende

Beispiele:

  • 32eFVfGDg891Be5e7293e54z1D23110M3ZU3FMjb30Z9a740Ej0jz4
  • b280R72b48eOm77a25YCj093DE5d9549Gc73Jg8TdD9Z0Nj4b98760
  • 051b33654C0Eg201cfW0e6NA4b9614ze8D2FN49E12Y0zY557aUCb8
  • y67Q86ffd83G0z00M0Z152f7O2ADcY313gD7a774fc5FF069zdb5b7

Dies ist nicht sehr konfigurierbar, um eine Schnittstelle für Benutzer zu erstellen, aber für einige Zwecke ist das in Ordnung. Erhöhen Sie die Anzahl der Zeichen, um das Fehlen von Sonderzeichen zu berücksichtigen.

Adam
quelle
3
  1. Erstellen Sie eine Datei mit diesem Code.
  2. Nennen Sie es wie in den Kommentaren.

    <?php 
    
    /**
    * @usage  :
    *       include_once($path . '/Password.php');
    *       $Password = new Password;
    *       $pwd = $Password->createPassword(10);
    *       return $pwd;
    * 
    */
    
    class Password {
    
        public function createPassword($length = 15) {
            $response = [];
            $response['pwd'] = $this->generate($length);
            $response['hashPwd'] = $this->hashPwd( $response['pwd'] );
            return $response;
        }
    
        private function generate($length = 15) {
            $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(){}/?,><";
            return substr(str_shuffle($chars),0,$length);
        }
    
        private function hashPwd($pwd) {
            return hash('sha256', $pwd);
        }
    
    }
    
    ?>
waz
quelle
2

Ich habe ein umfassenderes und sichereres Passwortskript erstellt. Dadurch wird eine Kombination aus zwei Großbuchstaben, zwei Kleinbuchstaben, zwei Zahlen und zwei Sonderzeichen erstellt. Insgesamt 8 Zeichen.

$char = [range('A','Z'),range('a','z'),range(0,9),['*','%','$','#','@','!','+','?','.']];
$pw = '';
for($a = 0; $a < count($char); $a++)
{
    $randomkeys = array_rand($char[$a], 2);
    $pw .= $char[$a][$randomkeys[0]].$char[$a][$randomkeys[1]];
}
$userPassword = str_shuffle($pw);
Monrejames
quelle
1
//define a function. It is only 3 lines!   
function generateRandomPassword($length = 5){
    $chars = "0123456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
    return substr(str_shuffle($chars),0,$length);
}

//usage
echo generateRandomPassword(5); //random password legth: 5
echo generateRandomPassword(6); //random password legth: 6
echo generateRandomPassword(7); //random password legth: 7
Hakiko
quelle
Das ist eigentlich (sehr?) Falsch. Tatsächlich wird jedes Zeichen aus dem Alphabet nur einmal verwendet, wodurch der Platz aller möglichen Werte (die für das Knacken relevant sind) erheblich verkleinert wird.
Radoslav Bodo
0

Erzeugt ein sicheres Passwort der Länge 8, das mindestens einen Kleinbuchstaben, einen Großbuchstaben, eine Ziffer und ein Sonderzeichen enthält. Sie können auch die Länge im Code ändern.

function checkForCharacterCondition($string) {
    return (bool) preg_match('/(?=.*([A-Z]))(?=.*([a-z]))(?=.*([0-9]))(?=.*([~`\!@#\$%\^&\*\(\)_\{\}\[\]]))/', $string);
}

$j = 1;

function generate_pass() {
    global $j;
    $allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_{}[]';
    $pass = '';
    $length = 8;
    $max = mb_strlen($allowedCharacters, '8bit') - 1;
    for ($i = 0; $i < $length; ++$i) {
        $pass .= $allowedCharacters[random_int(0, $max)];
    }

    if (checkForCharacterCondition($pass)){
        return '<br><strong>Selected password: </strong>'.$pass;
    }else{
        echo 'Iteration '.$j.':  <strong>'.$pass.'</strong>  Rejected<br>';
        $j++;
        return generate_pass();
    }

}

echo generate_pass();
Zihad Ul Islam
quelle
0

Diese Funktion generiert ein Passwort basierend auf den Regeln in den Parametern

function random_password( $length = 8, $characters = true, $numbers = true, $case_sensitive = true, $hash = true ) {

    $password = '';

    if($characters)
    {
        $charLength = $length;
        if($numbers) $charLength-=2;
        if($case_sensitive) $charLength-=2;
        if($hash) $charLength-=2;
        $chars = "abcdefghijklmnopqrstuvwxyz";
        $password.= substr( str_shuffle( $chars ), 0, $charLength );
    }

    if($numbers)
    {
        $numbersLength = $length;
        if($characters) $numbersLength-=2;
        if($case_sensitive) $numbersLength-=2;
        if($hash) $numbersLength-=2;
        $chars = "0123456789";
        $password.= substr( str_shuffle( $chars ), 0, $numbersLength );
    }

    if($case_sensitive)
    {
        $UpperCaseLength = $length;
        if($characters) $UpperCaseLength-=2;
        if($numbers) $UpperCaseLength-=2;
        if($hash) $UpperCaseLength-=2;
        $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $password.= substr( str_shuffle( $chars ), 0, $UpperCaseLength );
    }

    if($hash)
    {
        $hashLength = $length;
        if($characters) $hashLength-=2;
        if($numbers) $hashLength-=2;
        if($case_sensitive) $hashLength-=2;
        $chars = "!@#$%^&*()_-=+;:,.?";
        $password.= substr( str_shuffle( $chars ), 0, $hashLength );
    }

    $password = str_shuffle( $password );
    return $password;
}
Behiry
quelle
0

Hier ist meine Einstellung zur zufälligen einfachen Generierung von Passwörtern.

Es stellt sicher, dass das Passwort Zahlen, Groß- und Kleinbuchstaben sowie mindestens 3 Sonderzeichen enthält.

Die Länge des Passworts liegt zwischen 11 und 30.

function plainPassword(): string
{
    $numbers = array_rand(range(0, 9), rand(3, 9));
    $uppercase = array_rand(array_flip(range('A', 'Z')), rand(2, 8));
    $lowercase = array_rand(array_flip(range('a', 'z')), rand(3, 8));
    $special = array_rand(array_flip(['@', '#', '$', '!', '%', '*', '?', '&']), rand(3, 5));

    $password = array_merge(
        $numbers,
        $uppercase,
        $lowercase,
        $special
    );

    shuffle($password);

    return implode($password);
}
Sebastian Sulinski
quelle