Générer un mot de passe aléatoire en php


192

J'essaye de générer un mot de passe aléatoire en php.

Cependant, j'obtiens tous les 'a' et le type de retour est de type array et je voudrais que ce soit une chaîne. Des idées sur la façon de corriger le code?

Merci.

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

9
Aucune des réponses n'utilise un générateur de nombres aléatoires sécurisé , que vous voulez pour un mot de passe.
Scott Arciszewski

4
Les visiteurs doivent obtenir des informations potentiellement liées à la sécurité d'une source qui peut être mise à jour correctement, et non d'une question fermée à de nouvelles réponses. Je supprime les réponses à ce doublon afin que les visiteurs lisent à la place les réponses à la question ouverte. (Si cette question est un jour rouverte, les réponses ne seront pas supprimées.)
Jeremy

6
@JeremyBanks La question n'indique nulle part qu'un mot de passe cryptographiquement sécurisé est requis. Pour certaines personnes, les réponses en utilisant /dev/randomsont suffisantes car la question ne demande pas de mot de passe " sécurisé " (et ne devrait pas être modifiée pour contenir cela car cela modifierait le sens de la question d'origine). Bien que je sois tout à fait pour la sécurité, je pense que cette bombe de tapis n'a pas été entièrement pensée. Tout comme l'utilisation mysql_*, les réponses sont toujours valides, mais doivent être marquées comme non sécurisées. Peut-être est-ce quelque chose que SO doit inclure comme logiciel supplémentaire - la capacité d' avertir d'un code non sécurisé?
Jimbo

6
@JeremyBanks Pouvez-vous rétablir les réponses à cette question? Ce n'est pas parce que c'est un doublon que cela signifie que les réponses sont fausses (j'ai voté accidentellement pour la réouverture, je suis d'accord que c'est un doublon). Cela n'a aucun sens de supprimer les réponses, envisagez plutôt de supprimer cette question et de migrer les réponses vers l'autre question (je l'ai déjà vue).
Naftali aka Neal

7
@JeremyBanks si vous voulez que quelque chose ne soit pas rouvert, verrouillez-le. Sinon, 99% des gens le rouvriront et créeront tout un désordre. Personnellement, je suis totalement en désaccord avec la suppression des réponses hautement notées comme ça, mais je ne peux pas vous battre à ce sujet
Shadow Wizard is Ear For You

Réponses:


269

Avertissement de sécurité : rand()n'est pas un générateur de nombres pseudo-aléatoires cryptographiquement sécurisé. Cherchez ailleurs pour générer une chaîne pseudo-aléatoire cryptographiquement sécurisée en PHP .

Essayez ceci (utilisez à la strlenplace de count, car countsur une chaîne est toujours 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
}

Démo: http://codepad.org/UL8k4aYK


26
Semble plus simple à utiliser $pass .= $alphabet[$n].
Matthieu

34
Générer un mot de passe à l' aide de rand est une très mauvaise idée. Ce n'est pas un PRNG sécurisé. (et non mt_randn'est pas mieux non plus)
CodesInChaos

19
La question est de générer un mot de passe . Le code pour générer un mot de passe doit clairement utiliser des nombres aléatoires sécurisés.
CodesInChaos

10
Pour la même raison qu'il ne s'agit pas d' une question en double, cette réponse est incorrecte, car la question concerne la génération d'un mot de passe et non une chaîne aléatoire . Cette réponse fournit une approche terriblement non sécurisée pour générer un mot de passe. Veuillez utiliser la réponse de @ user3260409 ci-dessous, où openssl_random_pseudo_bytes()est utilisé à la place derand()
Désolé-Im-a-N00b

35
J'ai vu votre code non sécurisé en production et je souhaite l'arrêter à la source. Vous avez BESOIN d' un caractère aléatoire sécurisé cryptographiquement pour les mots de passe.
Scott Arciszewski

126

TL; DR:

  • Utilisez random_int()et les données random_str()ci-dessous.
  • Si vous ne l'avez pas random_int(), utilisez random_compat .

Explication:

Puisque vous générez un mot de passe , vous devez vous assurer que le mot de passe que vous générez est imprévisible, et le seul moyen de vous assurer que cette propriété est présente dans votre implémentation est d'utiliser un générateur de nombres pseudo-aléatoires (CSPRNG) cryptographiquement sécurisé .

L'exigence d'un CSPRNG peut être assouplie pour le cas général des chaînes aléatoires, mais pas lorsque la sécurité est impliquée.

La réponse simple, sécurisée et correcte à la génération de mots de passe en PHP est d'utiliser RandomLib et de ne pas réinventer la roue. Cette bibliothèque a été vérifiée par des experts en sécurité de l'industrie, ainsi que par moi-même.

Pour les développeurs qui préfèrent inventer votre propre solution, PHP 7.0.0 le fournira random_int()à cet effet. Si vous utilisez toujours PHP 5.x, nous avons écrit un polyfill PHP 5 pourrandom_int() que vous puissiez utiliser la nouvelle API avant la sortie de PHP 7. Utiliser notre random_int()polyfill est probablement plus sûr que d'écrire votre propre implémentation.

Avec un générateur d'entiers aléatoires sécurisé à portée de main, générer une chaîne aléatoire sécurisée est plus facile que le gâteau:

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

2
RandomLib n'a pas été mis à jour depuis plus de deux ans maintenant. Son utilisation sur une version PHP récente (7.1.25 dans mon cas) lance des avertissements de dépréciation pour diverses mcrypt_*fonctions. Je peux voir sur un fil de discussion que vous avez bifurqué la bibliothèque parce que vous ne parvenez pas à mettre la main sur @ircmaxell, mais votre fourchette dit «échec de la construction» sur Travis. Souhaitez-vous mettre à jour cette réponse (qui apparaît toujours assez élevée sur Google)?
Janus Bahs Jacquet

1
Bonne prise! Il doit être supprimé.
Scott Arciszewski

115

Je sais que vous essayez de générer votre mot de passe d'une manière spécifique, mais vous voudrez peut-être également examiner cette méthode ...

$bytes = openssl_random_pseudo_bytes(2);

$pwd = bin2hex($bytes);

Il est extrait du site php.net et crée une chaîne qui est deux fois la longueur du nombre que vous avez mis dans la fonction openssl_random_pseudo_bytes. Ainsi, ce qui précède créerait un mot de passe de 4 caractères.

En bref...

$pwd = bin2hex(openssl_random_pseudo_bytes(4));

Créerait un mot de passe de 8 caractères.

Notez cependant que le mot de passe ne contient que les chiffres 0-9 et les lettres minuscules af!


13
Si vous voulez un mot de passe en majuscules, minuscules et chiffres, essayez ceci: gist.github.com/zyphlar/7217f566fc83a9633959
willbradley

1
@ زياد Dit qui? Si le générateur utilisait des octets 7 bits, je serais d'accord avec vous, mais il openssl_random_pseudo_bytes()s'agit d'un puissant générateur d'aléa binaire complet et ne nécessite pas de mélange supplémentaire. Je profite également de l'occasion pour souligner qu'il est dangereux de supposer que l'empilement de plusieurs méthodes de cryptage rendra quelque chose de plus aléatoire, dans certains cas, cela peut en fait être exactement le contraire en raison de l'accumulation de collisions de hachage.
Havenard

58

Petit code avec 2 lignes.

démo: http://codepad.org/5rHMHwnH

function rand_string( $length ) {

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

}

echo rand_string(8);

avec rand_string, vous pouvez définir la quantité de caractères qui sera créée.


21
Bien, bien que vous n'obtiendrez pas de caractères répétés en utilisant cette approche, ce qui pourrait être indésirable.
Hobo

11
Cette fonction est terrible pour générer des mots de passe longs. Premièrement, si $ length est plus long que la chaîne $ chars, vous ne recevrez pas une chaîne aussi longue que la longueur que vous avez entrée, mais la longueur de la chaîne de caractères. En outre, vous êtes garanti seulement 1 de chaque personnage sans doublon. Il ne garantit pas non plus l'utilisation d'une majuscule ou d'un nombre qui est assez souvent une exigence (sauf bien sûr si votre longueur est supérieure à 26 en raison du défaut précédent)
Programster

Qu'en est-il de ces @Programster et @Hobo? substr(str_shuffle(str_repeat($chars,$length)),0,$length);
Charles-Édouard Coste

@ Charles-EdouardCoste semble fonctionner assez bien (surtout si vous ajoutez des caractères spéciaux). Bien que cela ne garantisse toujours pas au moins un de chaque type de caractère. La seule chose qui me dérange est de répéter l'ensemble du jeu de caractères par la longueur du mot de passe souhaité, mais cela garantit que les caractères du mot de passe généré ne doivent pas être uniques et n'ont pas d'impact notable sur les performances en une seule utilisation.
Programster

Je suis d'accord. Il vaut probablement mieux ne pas choisir un algorithme sur son nombre de lignes. Au fait, si l'objectif principal est simplement de générer un mot de passe temporaire lors de la création d'un nouvel utilisateur sur un site Web, cela répondrait aux besoins, je suppose.
Charles-Édouard Coste

43

Si vous êtes sur PHP7, vous pouvez utiliser la random_int()fonction:

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

Ancienne réponse ci-dessous:

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

12
ne pas utiliser mt_randpour générer un mot de passe.
CodesInChaos du

2
@CodesInChaos c'est mieux que rand () qui est ce que l'exemple ci-dessus utilise. openssl_random_pseudo_bytes () est préféré selon le manuel PHP.
willbradley

4
@willbradley La qualité de la graine est tout aussi mauvaise mt_rand, donc elle ne convient toujours à aucune utilisation de sécurité.
CodesInChaos du

2
vous voyez c'est ce qui m'ennuie + ChaosInCodes. Vous n'avez pas regardé la question, vous venez de faire des déclarations génériques répétées une charge de croyances mal tenues. En bref: le bon conseil pour une question totalement différente. Les mots de passe aléatoires sont très bien. Ils sont probablement à utiliser uniquement en "x". Honnêtement, si vous concevez votre système sans verrouillage chronométré et détection DOS et "x essaie alors -> verrouillé", vous le faites mal. IL EST IMPOSSIBLE de deviner un mot de passe mt_rand avec de telles mesures en place. À l'inverse, l'utilisation de mt_rand ne rendra pas plus FACILE la force brute d'un mot de passe. Ce ne sera tout simplement pas le cas.
Mr Heelis

1
Je n'utiliserais pas \ in$chars
Pedro Lobito

36

En une seule ligne:

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

11
Cela empêche la réutilisation des mêmes lettres car elles se mélangent simplement mais ne se produisent pas plus d'une fois.
nickdnk

8
Inutile de dire que personne ne devrait optimiser sa fonction de génération de mot de passe en fonction du nombre de lignes. Même si le RNG utilisé était sécurisé (ce n'est pas le cas), éviter les caractères répétés tout en générant un mot de passe de 10 caractères vous fait passer de ~ 52 bits d'entropie à ~ 50 bits d'entropie (~ 4x plus rapide à craquer). Si vous étendiez cela à 20 caractères, la non-répétition vous ramènerait de ~ 103 bits à ~ 94 bits (~ 512x plus rapide à craquer).
Jeremy

1
Cette méthode me rappelle la faille dans le code Enigma Lol
hatef

4
substr(str_shuffle(str_repeat($chars,$length)),0,$length); Entropie restaurée
Charles-Édouard Coste

27

Votre meilleur pari est la bibliothèque RandomLib d'ircmaxell .

Exemple d'utilisation:

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

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

Il produit des chaînes qui sont plus fortement aléatoires que les fonctions aléatoires normales comme shuffle()et rand()(ce que vous voulez généralement pour les informations sensibles comme les mots de passe, les sels et les clés).


4
C'est la bonne réponse. N'utilisez pas rand()ou mt_rand().
Scott Arciszewski

1
C'est peut-être la réponse la plus sûre (je ne sais pas comment elle se compare random_bytes), mais cela ne rend pas les randréponses incorrectes.
Cerbrus


8
@Cerbrus: Bien sûr, cette réponse ne donne pas de réponses rand()incorrectes. Ils sont tous incorrects par eux-mêmes!
Deduplicator

15

Je vais publier une réponse car certaines des réponses existantes sont proches mais ont l'une des suivantes:

  • un espace de caractère plus petit que ce que vous vouliez afin que soit le forçage brutal soit plus facile, soit le mot de passe doit être plus long pour la même entropie
  • un RNG qui n'est pas considéré comme sécurisé cryptographiquement
  • une exigence pour une bibliothèque tierce et j'ai pensé qu'il pourrait être intéressant de montrer ce qu'il faudrait pour le faire vous-même

Cette réponse contournera le count/strlenproblème car la sécurité du mot de passe généré, du moins à mon humble avis, transcende la façon dont vous y parvenez. Je vais également supposer que PHP> 5.3.0.

Décomposons le problème en ses parties constituantes qui sont:

  1. utiliser une source sécurisée d'aléa pour obtenir des données aléatoires
  2. utiliser ces données et les représenter comme une chaîne imprimable

Pour la première partie, PHP> 5.3.0 fournit la fonction openssl_random_pseudo_bytes. Notez que bien que la plupart des systèmes utilisent un algorithme cryptographique fort, vous devez vérifier afin que nous utilisions un wrapper:

/**
 * @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;
}

Pour la deuxième partie, nous utiliserons base64_encodecar il prend une chaîne d'octets et produira une série de caractères qui ont un alphabet très proche de celui spécifié dans la question d'origine. Si ne nous dérangeait pas avoir +, /et les =caractères apparaissent dans la chaîne finale et nous voulons un résultat au moins $ncaractères, nous pourrions simplement utiliser:

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

Le 3/4facteur est dû au fait que le codage en base64 aboutit à une chaîne dont la longueur est au moins un tiers plus grande que la chaîne d'octets. Le résultat sera exact pour $nêtre un multiple de 4 et jusqu'à 3 caractères de plus sinon. Étant donné que les caractères supplémentaires sont principalement le caractère de remplissage =, si, pour une raison quelconque, nous avions pour contrainte que le mot de passe soit d'une longueur exacte, nous pouvons le tronquer à la longueur souhaitée. Ceci est notamment dû au fait que pour un $nmot de passe donné , tous les mots de passe se termineraient par le même nombre de ceux-ci, de sorte qu'un attaquant ayant accès à un mot de passe de résultat aurait jusqu'à 2 caractères de moins à deviner.


Pour obtenir un crédit supplémentaire, si nous voulions respecter les spécifications exactes comme dans la question du PO, nous devrons faire un peu plus de travail. Je vais renoncer à l'approche de conversion de base ici et aller avec une approche rapide et sale. Les deux doivent générer plus de caractère aléatoire que ce qui sera utilisé dans le résultat de toute façon en raison de l'alphabet de 62 entrées.

Pour les caractères supplémentaires dans le résultat, nous pouvons simplement les supprimer de la chaîne résultante. Si nous commençons avec 8 octets dans notre chaîne d'octets, alors jusqu'à environ 25% des caractères base64 seraient ces caractères "indésirables", de sorte que le simple fait de rejeter ces caractères aboutit à une chaîne pas plus courte que l'OP souhaité. Ensuite, nous pouvons simplement le tronquer pour obtenir la longueur exacte:

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

Si vous générez des mots de passe plus longs, le caractère de remplissage =forme une proportion de plus en plus petite du résultat intermédiaire afin que vous puissiez implémenter une approche plus légère, si le drainage du pool d'entropie utilisé pour le PRNG est un problème.


1
Merci pour cet ajout. Aucune des réponses existantes openssl_random_pseudo_bytesn'a noté qui pourrait produire un résultat faible. Je n'avais pas réalisé que c'était le cas.
Jeremy du

14

Vous voulez strlen($alphabet), pas countde la constante alphabet(équivalent à 'alphabet').

Cependant, randn'est pas une fonction aléatoire appropriée à cet effet. Sa sortie peut être facilement prédite car elle est implicitement amorcée avec l'heure actuelle. De plus, randn'est pas sécurisé cryptographiquement; il est donc relativement facile de déterminer son état interne à partir de la sortie.

Au lieu de cela, lisez à partir de /dev/urandompour obtenir des données cryptographiques aléatoires.


12

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

par exemple. e0m6ngefmj4

ÉDITER

Comme je l'ai mentionné dans les commentaires, la longueur signifie que les attaques par force brute fonctionneraient mieux contre elle que le chronométrage des attaques, il n'est donc pas vraiment pertinent de s'inquiéter de «la sécurité du générateur aléatoire». La sécurité, en particulier pour ce cas d'utilisation, doit compléter la convivialité afin que la solution ci-dessus soit en fait suffisamment bonne pour le problème requis.

Cependant, juste au cas où vous tomberiez sur cette réponse en recherchant un générateur de chaînes aléatoires sécurisé (comme je suppose que certaines personnes l'ont basé sur les réponses), pour quelque chose comme la génération de jetons, voici à quoi ressemblerait un générateur de tels codes:

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

1
PS - c'est PHP - en utilisant simplement \ pour désigner l'espace de noms global.
Bob Gregor

Sauf que uniqid n'est pas sécurisé cryptographiquement. Utilisez plutôt rand (): base_convert (rand (78364164096, 2821109907455), 10, 36);
Benubird

7
@Benubird rand () n'est pas non plus sécurisé cryptographiquement, selon le manuel PHP. Le manuel suggère à la place openssl_random_pseudo_bytes ().
willbradley

Pour la plupart des cas d'utilisation, en particulier lorsque l'attaquant n'a pas accès à l'heure exacte, cela convient parfaitement et produit un mot de passe «temporaire» plus ou moins convivial. Si nous devions pousser cela à l'extrême, la longueur ici est beaucoup plus gênante que la fonction utilisée pour générer le nombre aléatoire.
srcspider

J'ai ajouté un exemple pour générer des chaînes entièrement sécurisées, pour les personnes intéressées; mais ne recommande vivement pas de l'utiliser lors de la génération de mots de passe temporaires pour les utilisateurs. Même en utilisant la version sécurisée, le problème de longueur s'applique toujours.
srcspider

9

Un autre (Linux uniquement)

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)), "=");
}

1
La lecture de 1024 octets pour les compresser en un hachage cryptographique de 128 bits de l'entropie est un peu inutile. En outre, les fread()tampons à 8192 octets par défaut, vous allez donc toujours en lire autant /dev/urandomavec le code donné. Cela ne fonctionnera pas non plus sous Windows. Félicitations pour l'utilisation d'un CSPRNG, cependant.
Scott Arciszewski

9

Être un peu plus intelligent:

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

vérifiez-le ici .


6

Essayez ceci avec des majuscules, des minuscules, des chiffres et des caractères spéciaux

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
}

Disons que nous avons besoin d'un pass à 10 chiffres

echo generatePassword(10);  

Exemple de sortie (s):

, IZCQ_IV \ 7

@wlqsfhT (d

1! 8 + 1 \ 4 @ uD


la randfonction n'est pas réellement sécurisée cryptographiquement, il pourrait donc être assez risqué de générer un mot de passe en l'utilisant
jeteon

6

Utilisez ce code simple pour générer un mot de passe med-strong 12 longueur

$password_string = '!@#$%*&abcdefghijklmnpqrstuwxyzABCDEFGHJKLMNPQRSTUWXYZ23456789';
$password = substr(str_shuffle($password_string), 0, 12);

C'est en fait (très?) Faux. Il n'utilise en fait chaque caractère de l'alphabet qu'une seule fois, ce qui réduit considérablement l'espace de toutes les valeurs possibles (pertinentes pour le craquage).
Radoslav Bodo le

3

Rapide un. Format simple, propre et cohérent si c'est ce que vous voulez

$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

Ceci est basé sur une autre réponse sur cette page, https://stackoverflow.com/a/21498316/525649

Cette réponse génère seulement caractères hexadécimaux, 0-9,a-f. Pour quelque chose qui ne ressemble pas à hexagone, essayez ceci:

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 renvoie une plus grande diffusion de caractères alphanumériques
  • rtrimsupprime le =parfois à la fin

Exemples:

  • 32eFVfGDg891Be5e7293e54z1D23110M3ZU3FMjb30Z9a740Ej0jz4
  • b280R72b48eOm77a25YCj093DE5d9549Gc73Jg8TdD9Z0Nj4b98760
  • 051b33654C0Eg201cfW0e6NA4b9614ze8D2FN49E12Y0zY557aUCb8
  • y67Q86ffd83G0z00M0Z152f7O2ADcY313gD7a774fc5FF069zdb5b7

Ce n'est pas très configurable pour créer une interface pour les utilisateurs, mais à certaines fins, ce n'est pas grave. Augmentez le nombre de caractères pour tenir compte du manque de caractères spéciaux.


3
  1. Créez un fichier contenant ce code.
  2. Appelez-le comme dans les commentaires.

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

2

J'ai créé un script de mot de passe plus complet et sécurisé. Cela créera une combinaison de deux majuscules, deux minuscules, deux chiffres et deux caractères spéciaux. Total 8 caractères.

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

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

C'est en fait (très?) Faux. Il n'utilise en fait chaque caractère de l'alphabet qu'une seule fois, ce qui réduit considérablement l'espace de toutes les valeurs possibles (pertinentes pour le craquage).
Radoslav Bodo le

0

Génère un mot de passe fort de longueur 8 contenant au moins une lettre minuscule, une lettre majuscule, un chiffre et un caractère spécial. Vous pouvez également modifier la longueur du code.

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

0

Cette fonction générera un mot de passe basé sur les règles des paramètres

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

0

Voici ma prise à l'aide de génération de mot de passe aléatoire.

Il garantit que le mot de passe comporte des chiffres, des lettres majuscules et minuscules ainsi qu'un minimum de 3 caractères spéciaux.

La longueur du mot de passe sera comprise entre 11 et 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);
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.