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;
}
/dev/random
sont 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'utilisationmysql_*
, 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é?Réponses:
Essayez ceci (utilisez à la
strlen
place decount
, carcount
sur une chaîne est toujours1
):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
la source
$pass .= $alphabet[$n]
.mt_rand
n'est pas mieux non plus)openssl_random_pseudo_bytes()
est utilisé à la place derand()
TL; DR:
random_int()
et les donnéesrandom_str()
ci-dessous.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 notrerandom_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; }
la source
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)?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!
la source
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.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);
la source
substr(str_shuffle(str_repeat($chars,$length)),0,$length);
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; }
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; }
la source
mt_rand
pour générer un mot de passe.mt_rand
, donc elle ne convient toujours à aucune utilisation de sécurité.$chars
En une seule ligne:
substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') , 0 , 10 )
la source
substr(str_shuffle(str_repeat($chars,$length)),0,$length);
Entropie restauréeVotre 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()
etrand()
(ce que vous voulez généralement pour les informations sensibles comme les mots de passe, les sels et les clés).la source
rand()
oumt_rand()
.random_bytes
), mais cela ne rend pas lesrand
réponses incorrectes.rand
n'est pas un bon choix pour les mots de passerand()
incorrectes. Ils sont tous incorrects par eux-mêmes!Je vais publier une réponse car certaines des réponses existantes sont proches mais ont l'une des suivantes:
Cette réponse contournera le
count/strlen
problè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:
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_encode
car 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$n
caractères, nous pourrions simplement utiliser:base64_encode(strong_random_bytes(intval(ceil($n * 3 / 4))));
Le
3/4
facteur 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$n
mot 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.la source
openssl_random_pseudo_bytes
n'a noté qui pourrait produire un résultat faible. Je n'avais pas réalisé que c'était le cas.Vous voulez
strlen($alphabet)
, pascount
de la constantealphabet
(équivalent à'alphabet'
).Cependant,
rand
n'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,rand
n'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/urandom
pour obtenir des données cryptographiques aléatoires.la source
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); } }
la source
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)), "="); }
la source
fread()
tampons à 8192 octets par défaut, vous allez donc toujours en lire autant/dev/urandom
avec le code donné. Cela ne fonctionnera pas non plus sous Windows. Félicitations pour l'utilisation d'un CSPRNG, cependant.Être un peu plus intelligent:
function strand($length){ if($length > 0) return chr(rand(33, 126)) . strand($length - 1); }
vérifiez-le ici .
la source
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 }
echo generatePassword(10);
Exemple de sortie (s):
, IZCQ_IV \ 7
@wlqsfhT (d
1! 8 + 1 \ 4 @ uD
la source
rand
fonction 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'utilisantUtilisez 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);
la source
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);
la source
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ériquesrtrim
supprime le=
parfois à la finExemples:
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.
la source
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); } } ?>
la source
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);
la source
//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
la source
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();
la source
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; }
la source
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); }
la source