it-swarm.com.de

Generieren eines zufälligen Passworts in PHP

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

Allerdings bekomme ich alle 'a' und der Rückgabetyp ist vom Typ Array und ich möchte, dass es ein String ist. Irgendwelche Ideen zur Korrektur des Codes?

Vielen Dank.

function randomPassword() {
    $alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
    for ($i = 0; $i < 8; $i++) {
        $n = Rand(0, count($alphabet)-1);
        $pass[$i] = $alphabet[$n];
    }
    return $pass;
}
173
nunos

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

Versuchen Sie dies (verwenden Sie strlen anstelle von count, da count für eine Zeichenfolge immer 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

240
Neal

TL; DR:

  • Verwenden Sie random_int() und die unten angegebene random_str().
  • Wenn Sie nicht über random_int() verfügen, verwenden Sie random_compat .

Erläuterung:

Da Sie ein Kennwort generieren, müssen Sie sicherstellen, dass das generierte Kennwort nicht vorhersehbar ist und dass diese Eigenschaft nur in Ihrer Implementierung vorhanden ist ist die Verwendung eines kryptografisch sicheren Pseudozufallszahlengenerators (CSPRNG).

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

Die einfache, sichere und korrekte Antwort auf die Kennwortgenerierung in PHP lautet RandomLib und erfindet das Rad nicht neu. Diese Bibliothek wurde von Sicherheitsexperten der Branche sowie von mir selbst geprüft.

Für Entwickler, die es vorziehen, eine eigene Lösung zu erfinden, bietet PHP 7.0.0 zu diesem Zweck random_int() . Wenn Sie noch auf PHP 5.x sind, haben wir ein PHP 5-Polyfill für random_int() geschrieben, damit Sie die neue API vor PHP 7 verwenden können es ist veröffentlicht worden. Die Verwendung unserer random_int() Polyfill ist wahrscheinlich sicherer als das Schreiben einer eigenen Implementierung.

Mit einem sicheren Zufallsgenerator ist das Generieren einer sicheren Zufallszeichenfolge einfacher als mit pie:

<?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;
}
108

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

$bytes = openssl_random_pseudo_bytes(2);

$pwd = bin2hex($bytes);

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

Zusamenfassend...

$pwd = bin2hex(openssl_random_pseudo_bytes(4));

Würde ein Passwort erstellen, das 8 Zeichen lang ist.

Beachten Sie jedoch, dass das Passwort nur die Ziffern 0-9 und die Kleinbuchstaben a-f enthält!

105
user3260409

Kleiner 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 Charakter erstellt werden soll.

52
BSQ

In einer Zeile:

substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') , 0 , 10 )
36
Sandra

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

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

  $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`[email protected]#$%^&*()_+,./<>?;:[]{}\|';

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

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

  return $str;
}
36
PeeHaa

Ihre beste Wette 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 im Allgemeinen für vertrauliche Informationen wie Kennwörter, Salt und Schlüssel gewünscht wird).

26
Madara Uchiha

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 Erzwingen von Brute einfacher ist oder das Kennwort für dieselbe Entropie länger sein muss
  • a RNG das gilt nicht als kryptografisch sicher
  • eine Anforderung 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 Problem count/strlen, Da die Sicherheit des generierten Passworts, zumindest meiner Meinung nach, über die Art und Weise hinausgeht, wie Sie dorthin gelangen. Ich gehe auch von PHP> 5.3.0 aus.

Teilen wir das Problem in die folgenden Bestandteile auf:

  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 jedoch überprüfen müssen, damit wir einen Wrapper verwenden:

/**
 * @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_encode , da 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 es uns nichts ausmacht, +, / Und = Zeichen in der letzten Zeichenfolge zu haben und wir möchten, dass das Ergebnis mindestens $n Zeichen lang ist könnte einfach verwenden:

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

Der Faktor 3/4 Beruht auf der Tatsache, dass die Base64-Codierung zu einer Zeichenfolge führt, deren Länge mindestens ein Drittel größer ist als die Bytezeichenfolge. Das Ergebnis ist genau, wenn $n Ein Vielfaches von 4 und ansonsten bis zu 3 Zeichen länger ist. Da es sich bei den zusätzlichen Zeichen überwiegend um das Füllzeichen = Handelt, können wir das Kennwort auf die gewünschte Länge kürzen, wenn wir aus irgendeinem Grund die Einschränkung hatten, dass es eine genaue Länge hat. Dies liegt insbesondere daran, dass für ein bestimmtes $n Alle Kennwörter mit derselben Nummer enden würden, sodass ein Angreifer, der Zugriff auf ein Ergebniskennwort hatte, bis zu 2 Zeichen weniger zu erraten hätte.


Wenn wir die genaue Spezifikation wie in der Frage des OP erfüllen wollten, müssten wir ein bisschen mehr arbeiten, um zusätzliche Kredite zu erhalten. Ich werde hier auf den Ansatz der Basiskonvertierung verzichten und mich für einen schnellen und schmutzigen Ansatz entscheiden. Beide müssen aufgrund des langen Alphabets mit 62 Einträgen ohnehin mehr Zufälligkeiten generieren, als im Ergebnis verwendet werden.

Für die zusätzlichen Zeichen im Ergebnis können wir sie einfach aus der resultierenden Zeichenfolge entfernen. Wenn wir mit 8 Bytes in unserer Byte-Zeichenfolge beginnen, wären 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 ist als das gewünschte OP. Dann können wir es einfach abschneiden, um auf die genaue Länge zu kommen:

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

Wenn Sie längere Passwörter generieren, bildet das Füllzeichen = Einen immer kleineren Anteil des Zwischenergebnisses, so dass Sie einen schlankeren Ansatz implementieren können, wenn der für PRNG verwendete Entropiepool leer ist eine Sorge.

14
jeteon

Sie möchten strlen($alphabet), nicht count der Konstante alphabet (entspricht 'alphabet').

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

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

14
phihag

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

z.B. e0m6ngefmj4

EDIT

Wie ich in den Kommentaren erwähnt habe, bedeutet die Länge, dass Brute-Force-Angriffe besser funktionieren als Timing-Angriffe, sodass es nicht wirklich relevant ist, 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 auf diese Antwort gestoßen sind, während Sie nach einem sicheren Zufallsgenerator gesucht haben (wie ich annehme, dass einige Leute auf den Antworten basieren).

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);
    }
}
11
srcspider

Dies ist im Grunde dasselbe wie das viel einfachere substr(md5(uniqid()), 0, 8);

11
Explosion Pills

Noch eine (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)), "=");
}
9
Askarel

Ein bisschen schlauer sein:

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

überprüfe es hier .

8
Amir Forsati

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

function generatePassword($_len) {

    $_alphaSmall = 'abcdefghijklmnopqrstuvwxyz';            // small letters
    $_alphaCaps  = strtoupper($_alphaSmall);                // CAPITAL LETTERS
    $_numerics   = '1234567890';                            // numerics
    $_specialChars = '`[email protected]#$%^&*()-_=+]}[{;:,<.>/?\'"\|';   // 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

6
Sanjeev

Verwenden Sie diesen einfachen Code, um ein medizinisch sicheres Kennwort 12 zu generieren

$password_string = '[email protected]#$%*&abcdefghijklmnpqrstuwxyzABCDEFGHJKLMNPQRSTUWXYZ23456789';
$password = substr(str_shuffle($password_string), 0, 12);
6
Pablo Martinez
  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 = "[email protected]#$%^&*(){}/?,><";
            return substr(str_shuffle($chars),0,$length);
        }
    
        private function hashPwd($pwd) {
            return hash('sha256', $pwd);
        }
    
    }
    
    ?>
    
3
waz

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);
3

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

Diese Antwort generiert 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 Anzahl alphanumerischer Zeichen zurück
  • rtrim entfernt das = manchmal am ende

Beispiele:

  • 32eFVfGDg891Be5e7293e54z1D23110M3ZU3FMjb30Z9a740Ej0jz4
  • b280R72b48eOm77a25YCj093DE5d9549Gc73Jg8TdD9Z0Nj4b98760
  • 051b33654C0Eg201cfW0e6NA4b9614ze8D2FN49E12Y0zY557aUCb8
  • y67Q86ffd83G0z00M0Z152f7O2ADcY313Gd7a774fc5FF069zdb5b7

Dies ist nicht sehr konfigurierbar, um eine Benutzeroberfläche 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.

3
Adam

Ich habe ein umfassenderes und sicheres Passwort-Skript 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);
2
monrejames
//define a function. It is only 3 lines!   
function generateRandomPassword($length = 5){
    $chars = "123456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
    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
0
hakiko

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]))(?=.*([~`\[email protected]#\$%\^&\*\(\)_\{\}\[\]]))/', $string);
}

$j = 1;

function generate_pass() {
    global $j;
    $allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`[email protected]#$%^&*()_{}[]';
    $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();
0
Zihad Ul Islam