Створення випадкового пароля в php


190

Я намагаюся генерувати випадковий пароль у php.

Однак я отримую всі '', і тип повернення - це тип масиву, і я хотів би, щоб це був рядок. Будь-які ідеї, як виправити код?

Дякую.

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

9
Жодна з відповідей не використовує захищений генератор випадкових чисел , який потрібно ввести для пароля.
Скотт Арчішевський

4
Відвідувачі повинні отримувати інформацію, пов’язану з безпекою, з джерела, яке можна оновити належним чином, а не питання, закрите для нових відповідей. Я видаляю відповіді на цей дублікат, щоб відвідувачі замість цього прочитали відповіді на відкрите запитання. (Якщо це питання коли-небудь повторно відкриється, відповіді буде скасовано.)
Джеремі Бенкс

6
@JeremyBanks Ніде не вказано, що криптографічно захищений пароль не потрібен. Для деяких людей /dev/randomдостатньо відповідей , оскільки питання не вимагає " безпечного " пароля (і його не слід редагувати, щоб воно містило так, як це змінило б значення початкового запитання). Хоча я все для безпеки, я думаю, що ця килимова бомба не була продумана повністю. Як і використання mysql_*, відповіді все ще справедливі, але повинні бути позначені як небезпечні. Можливо, це щось, що потрібно включити як додаткове програмне забезпечення - можливість попереджати про небезпечний код?
Jimbo

6
@JeremyBanks Чи можете ви відновити відповіді на це запитання? Тільки тому, що це дублікат, це не означає, що відповіді неправильні (я випадково проголосував за повторне відкриття, я згоден, що це дублікат). Видаляти відповіді немає сенсу. Розгляньте замість цього видалення цього питання та переміщення відповідей на інше питання (я бачив це вже раніше).
Naftali aka Neal

7
@JeremyBanks Якщо ви хочете, щоб щось не було відкрито, заблокуйте його. Інакше 99% людей знову відкриють його і створять цілий безлад. Особисто я не згоден із видаленням високо оцінених відповідей просто так, але не можу боротися з вами через це
Shadow Wizard є Ear For You

Відповіді:


258

Попередження безпеки : rand()не є криптографічно захищеним генератором псевдовипадкових чисел. Шукайте в іншому місці для генерації криптографічно захищеної псевдовипадкової рядки в PHP .

Спробуйте це (використовуйте strlenзамість count, тому що countв рядку завжди 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
}

Демо: http://codepad.org/UL8k4aYK


24
Здається, більш простою у використанні $pass .= $alphabet[$n].
Метью

33
Створення пароля за допомогою rand - це дуже погана ідея. Це не безпечний PRNG. (та й mt_randне краще)
CodesInChaos

19
Питання полягає у створенні пароля . Код для створення пароля очевидно потребує використання захищених випадкових чисел.
CodesInChaos

10
З тієї ж причини, оскільки це не повторне запитання, ця відповідь є неправильною, оскільки мова йде про генерування пароля, а не про випадкову рядок . Ця відповідь дає надзвичайно небезпечний підхід до створення пароля. Будь ласка, використовуйте відповідь @ user3260409 нижче, де openssl_random_pseudo_bytes()використовується замістьrand()
Вибачте-Im-a-N00b

35
Я бачив ваш незахищений код у виробництві і хочу зупинити його біля джерела. Ви НЕОБХІДНО криптографічно захищати випадковість паролів.
Скотт Арчішевський

122

TL; DR:

  • Використання random_int()та наведене random_str()нижче.
  • Якщо у вас немає random_int(), використовуйте random_compat .

Пояснення:

Оскільки ви генеруєте пароль , вам потрібно переконатися, що створений вами пароль є непередбачуваним, і єдиний спосіб забезпечити присутність цього властивості у вашій реалізації - використовувати криптографічно захищений генератор псевдовипадкових чисел (CSPRNG).

Вимога до CSPRNG може бути послабленою для загального випадку випадкових рядків, але не тоді, коли йдеться про захист.

Проста, безпечна та правильна відповідь на генерацію паролів у PHP - це використовувати RandomLib і не винаходити колесо. Цю бібліотеку перевіряли експерти галузі безпеки, а також я.

Для розробників, які віддають перевагу винайдення власного рішення, PHP 7.0.0 надасть random_int()для цієї мети. Якщо ви все ще знаходитесь на PHP 5.x, ми написали PHP 5 polyfill для того,random_int() щоб ви могли використовувати новий API до виходу PHP 7. Використання нашої random_int()полісистеми, напевно, безпечніше, ніж написання власної реалізації.

З захищеним генератором випадкових цілих чисел в руці, генерувати захищений випадковий рядок простіше, ніж пиріг:

<?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 не оновлювався вже більше двох років. Використовуючи його в недавній збірці PHP (7.1.25 в моєму випадку), викидає попередження про депресію для різних mcrypt_*функцій. Я бачу на темі проблеми, що ви розпрощалися з бібліотекою через те, що не змогли отримати доступ до @ircmaxell, але ваш форк говорить: "Збій невдалий" на Travis. Чи хотіли б ви оновити цю відповідь (яка все ще виявляється досить високою в Google)?
Jaus Bahs Jacquet

1
Гарний улов! Його потрібно зняти.
Скотт

113

Я знаю, що ви намагаєтесь генерувати свій пароль певним чином, але ви, можливо, захочете переглянути і цей метод ...

$bytes = openssl_random_pseudo_bytes(2);

$pwd = bin2hex($bytes);

Він береться з сайту php.net, і він створює рядок, що вдвічі перевищує число, яке ви вводите у функції openssl_random_pseudo_bytes. Отже, описане вище створить пароль довжиною 4 символи.

Коротко...

$pwd = bin2hex(openssl_random_pseudo_bytes(4));

Створить пароль довжиною 8 символів.

Зауважте, що пароль містить лише цифри 0-9 та малі літери af!


13
Якщо ви хочете ввести великі, малі та чисті
паролі

@ زياد Хто говорить? Якби генератор використовував 7-бітні байти, я погодився б з вами, але openssl_random_pseudo_bytes()це потужний повноцінний генератор випадкових байтів і не потребує подальшого перемішування. Також я ризикую зазначити, що небезпечно припустити, що укладання декількох методів шифрування зробить що-небудь більш випадковим, у деяких випадках насправді це може бути навпаки через накопичення хеширующих зіткнень.
Хавенард

56

Крихітний код з 2 рядками.

демонстрація: http://codepad.org/5rHMHwnH

function rand_string( $length ) {

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

}

echo rand_string(8);

за допомогою rand_string ви можете визначити, скільки символів буде створено.


21
Приємно, хоча ви не отримаєте жодних повторних персонажів, використовуючи такий підхід, що може бути небажаним.
Hobo

11
Ця функція жахлива для генерації довгих паролів. По-перше, якщо $ length більше, ніж рядок $ chars, то ви отримаєте рядок не стільки, скільки введена вами довжина, а довжина рядка символів. Крім того, вам гарантується лише 1 з кожного символу без копій. Це також не гарантує використання великої літери або цифри, що досить часто є вимогою (за винятком, звичайно, якщо ваша довжина перевищує 26 за попередньою помилкою)
Програміст

Що з цим @Programster та @Hobo? substr(str_shuffle(str_repeat($chars,$length)),0,$length);
Шарль-Едуард Косте

@ Charles-EdouardCoste, здається, працює досить добре (особливо, якщо ви кинете в якісь спеціальні символи). Хоча це все ще не гарантує принаймні одного з кожного типу символів. Єдине, що мене турбує, - це повторити весь набір символів за довжиною потрібного пароля, але це гарантує, що символи в створеному паролі не повинні бути унікальними та не мати помітного впливу на продуктивність при одному використанні.
Programster

Я погоджуюсь. Напевно, краще не вибирати алгоритм за його кількістю рядків. До речі, якщо головна мета - просто генерувати тимчасовий пароль при створенні нового користувача на веб-сайті, це, напевно, відповідало б потребам.
Charles-Édouard Coste

40

Якщо ви перебуваєте на PHP7, ви можете скористатися random_int()функцією:

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

12
не використовувати mt_randдля створення пароля.
CodesInChaos

2
@CodesInChaos це краще, ніж rand (), для чого використовується вищеприклад. Згідно з посібником з PHP, воліє openssl_random_pseudo_bytes ().
willbradley

4
@willbradley Якість насіння так само погано mt_rand, тому воно все ще непридатне для використання в безпеці.
CodesInChaos

2
Ви бачите, що це мене дратує + ChaosInCodes. Ви не розглядали питання, ви просто зробили кілька загальних тверджень, які повторювали навантаження погано переконаних. Коротше кажучи: правильна порада для абсолютно іншого питання. Випадкові паролі чудово. Вони, ймовірно, використовують лише "х". Досить чесно, якщо ви проектуєте свою систему без приурочених блокувань і виявлення DOS, і "x спроби потім -> заблоковані", то ви робите це неправильно. Вважати пароль mt_rand з такими заходами неможливо. І навпаки, використання mt_rand не дозволить ЛЕГІШЕ змусити пароль. Це просто не буде.
Містер Хеліс

1
Я б не використовував \ in$chars
CONvid19

36

В одному рядку:

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

11
Це запобігає повторному використанню тих самих букв, що вони просто перетасовуються, але не зустрічаються більше одного разу.
nickdnk

8
Потрібно сказати, що ніхто не повинен оптимізувати функцію створення пароля на основі кількості рядків. Навіть якщо використані RNG були безпечними (це не так), уникнення повторних символів під час генерування 10-символьного пароля приводить вас від ~ 52 біт ентропії до ~ 50 біт ентропії (~ 4 рази швидше зламати). Якщо ви продовжите це на 20 символів, повторення призведе до зниження від 103 біт до ~ 94 біт (~ 512x швидше зламати).
Джеремі Бенкс

1
Цей метод нагадує мені про ваду в коді Enigma Lol
hatef

4
substr(str_shuffle(str_repeat($chars,$length)),0,$length); Ентропія відновлена
Чарльз-Едуард Косте

27

Ваша найкраща ставка - бібліотека RandomLib від ircmaxell .

Приклад використання:

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

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

Вона виробляє струни , які більш сильно випадковим , ніж звичайні функції випадковості , як shuffle()і rand()(що зазвичай ви хочете для чутливої інформації , такої як паролі, солі і ключі).


4
Це правильна відповідь. Не використовуйте rand()або mt_rand().
Скотт Арчішевський

1
Це може бути найбільш безпечною відповіддю (не впевнений, з чим вона порівнюється random_bytes), але це не робить randвідповіді невірними.
Cerbrus


8
@Cerbrus: Впевнений, що ця відповідь не дає відповідей rand()неправильно. Вони невірно все самостійно!
Дедуплікатор

14

Ви хочете strlen($alphabet), не countпостійні alphabet(еквівалентні 'alphabet').

Однак randдля цієї мети не підходить випадкова функція. Його результат можна легко передбачити, оскільки він неявно засіяний поточним часом. Крім того, randне є криптографічно захищеним; Тому визначити його внутрішній стан за результатами порівняно легко.

Натомість читайте з, /dev/urandomщоб отримати криптографічно випадкові дані.


14

Я збираюся опублікувати відповідь, тому що деякі з існуючих відповідей близькі, але мають один із:

  • менший простір символів, ніж ви хотіли, так що грубе форсування простіше або пароль повинен бути довшим для тієї самої ентропії
  • ГСЧ , не рахується криптографічний безпечними
  • вимога до якоїсь сторонньої бібліотеки, і я подумав, що може бути цікаво показати, що може знадобитися зробити це самостійно

Ця відповідь обійде count/strlenпитання, оскільки безпека згенерованого пароля, принаймні IMHO, перевершує те, як ви туди потрапляєте. Я також припускаю PHP> 5.3.0.

Розбимо задачу на складові частини, які є:

  1. використовувати якесь захищене джерело випадковості для отримання випадкових даних
  2. використовувати ці дані і представляти їх як деякий рядок для друку

У першій частині PHP> 5.3.0 забезпечує функцію openssl_random_pseudo_bytes. Зауважте, що в більшості систем використовується криптографічно сильний алгоритм, ви повинні перевірити, щоб ми використовували обгортку:

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

У другій частині ми будемо використовувати, base64_encodeоскільки вона займає байт-рядок і створить ряд символів, які мають алфавіт, дуже близький до того, який зазначено в оригінальному запитанні. Якщо б ми не заперечували над тим +, /а =символи з’являються в заключній рядку і нам потрібен результат хоча б $nсимволів, ми можемо просто використовувати:

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

3/4Фактором є те, з - за того , що кодування base64 результатів у вигляді рядка , яка має довжину , щонайменше, третина більше , ніж рядки байтів. Результат буде точним, $nякщо в іншому випадку кратно 4 та до 3 символів. Оскільки зайві символи є переважно символом прокладки =, якщо ми з якихось причин мали обмеження, що пароль має бути точної довжини, то ми можемо скоротити його до потрібної довжини. Це особливо тому, що для даної дати $nвсі паролі закінчуватимуться однаковою кількістю таких, щоб зловмисник, який мав доступ до результату пароля, мав до 2 менших символів для здогадки.


Для додаткового кредиту, якби ми хотіли зустріти точну специфікацію, як у питанні про ОП, тоді нам доведеться зробити трохи більше роботи. Я тут відмовляюся від базового підходу до перетворення та йду з швидким та брудним. І те й інше потрібно створити більше випадковості, ніж все одно буде використано в результаті через 62 алфавіту довгого введення.

Для додаткових символів у результаті ми можемо просто відкинути їх від отриманого рядка. Якщо ми почнемо з 8-ти байт у нашому ряду байтів, то приблизно 25% символів base64 становитимуть ці "небажані" символи, так що просто відкидання цих символів призводить до рядка, не меншого, ніж хотів ОП. Тоді ми можемо просто усікати його, щоб прийти до точної довжини:

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

Якщо ви генеруєте більш довгі паролі, символ прокладки =утворює все меншу і меншу частку проміжного результату, щоб ви могли реалізувати менший підхід, якщо виснаження пулу ентропії, що використовується для PRNG, викликає занепокоєння.


1
Дякую за це доповнення. Жодна з існуючих відповідей не зазначила, що це openssl_random_pseudo_bytesможе призвести до слабкого результату. Я не усвідомлював, що це так.
Джеремі Бенкс

12

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

напр. e0m6ngefmj4

EDIT

Як я вже згадував у коментарях, тривалість означає, що грубі сили атаки будуть краще працювати проти цього, ніж часові атаки, тому не дуже важливо турбуватися про "наскільки безпечним був генератор випадкових випадків". Безпека, спеціально для даного випадку використання, повинна доповнювати зручність використання, тому вищезазначене рішення насправді досить добре для необхідної проблеми.

Однак на всякий випадок, коли ви натрапили на цю відповідь під час пошуку безпечного генератора випадкових рядків (як я вважаю, деякі люди базуються на відповідях), для чогось такого, як генерування жетонів, ось як би виглядав генератор таких кодів:

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 - це PHP - просто використовуючи \ для позначення глобального простору імен.
Боб Грегор

За винятком того, що uniqid не є криптографічно захищеним. Використовуйте натомість rand (): base_convert (rand (78364164096, 2821109907455), 10, 36);
Benubird

7
@Benubird rand () також не є криптографічно захищеним, відповідно до посібника PHP. Посібник пропонує натомість openssl_random_pseudo_bytes ().
willbradley

У більшості випадків використання, зокрема, коли зловмисник не має доступу до точного часу, це абсолютно чудово і створює приємний більш-менш людський "тимчасовий" пароль. Якби ми довели це до крайньої величини, тут довжина набагато складніше, ніж яка функція була використана для генерації випадкового числа.
srcspider

Я додав приклад для створення повністю захищених рядків для тих, хто цікавиться; але настійно не рекомендую використовувати це під час створення тимчасових паролів для користувачів. Навіть використовуючи захищену версію, проблема з довжиною все ще застосовується.
srcspider

9

Ще один (лише для 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)), "=");
}

1
Читання 1024 байтів для стискання в 128-бітовий криптографічний хеш ентропії трохи марно. Крім того, fread()буфери на 8192 байти за замовчуванням, так що ви завжди будете читати, що багато /dev/urandomз даним кодом. Це також не буде працювати в Windows. Кудо для використання CSPRNG, хоча.
Скотт Арчішевський

9

Бути трохи розумнішим:

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

перевірте це тут .


7

Використовуйте цей простий код для генерування середньо-сильного пароля довжиною 12

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

Це насправді (дуже?) Неправильно. Він фактично використовує кожну знаку з алфавіту лише один раз, тим самим сильно скорочуючи простір усіх можливих значень (стосується розтріскування).
Радослав Бодо

6

Спробуйте це з великими літерами, малими літерами, цифрами та спеціальними символами

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
}

Скажімо, нам потрібно 10 цифр пропуск

echo generatePassword(10);  

Приклади результатів:

, IZCQ_IV \ 7

@wlqsfhT (д

1! 8 + 1 \ 4 @ uD


randфункція практично не криптографически безпечний , так що може бути досить ризик для генерації пароля , використовуючи його
jeteon

3

Швидкий. Простий, чистий і послідовний формат, якщо це те, що ви хочете

$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

Це засновано на іншій відповіді на цій сторінці https://stackoverflow.com/a/21498316/525649

Ця відповідь генерує тільки шістнадцяткові символи, 0-9,a-f. Щоб щось не виглядало як шістнадцятковий, спробуйте:

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 повертає більш широке поширення буквено-цифрових знаків
  • rtrimвидаляє =іноді в кінці

Приклади:

  • 32eFVfGDg891Be5e7293e54z1D23110M3ZU3FMjb30Z9a740Ej0jz4
  • b280R72b48eOm77a25YCj093DE5d9549Gc73Jg8TdD9Z0Nj4b98760
  • 051b33654C0Eg201cfW0e6NA4b9614ze8D2FN49E12Y0zY557aUCb8
  • y67Q86ffd83G0z00M0Z152f7O2ADcY313gD7a774fc5FF069zdb5b7

Це не дуже налаштовується для створення інтерфейсу для користувачів, але для деяких цілей це нормально. Збільшити кількість знаків для врахування відсутності спеціальних символів.


3
  1. Створіть у ньому файл із цим кодом.
  2. Назвіть це як у коментарях.

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

Я створив більш повний і безпечний сценарій паролів. Це створить комбінацію двох великих літер, двох малих літер, двох чисел та двох спеціальних символів. Всього 8 символів.

$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

Це насправді (дуже?) Неправильно. Він фактично використовує кожну знаку з алфавіту лише один раз, тим самим сильно скорочуючи простір усіх можливих значень (стосується розтріскування).
Радослав Бодо

0

Створює надійний пароль довжиною 8, що містить принаймні одну малу літеру, одну велику літеру, одну цифру та один спеціальний символ. Ви також можете змінити довжину в коді.

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

Ця функція генерує пароль на основі правил у параметрах

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

Ось мій випадковий помічник простого генерації пароля.

Він гарантує, що в паролі є цифри, великі та малі літери, а також мінімум 3 спеціальні символи.

Довжина пароля буде від 11 до 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);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.