Генерация случайного пароля в 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;
}
nunos
источник
9
Ни один из ответов не использует безопасный генератор случайных чисел , который вы хотите для пароля.
Скотт Аркишевский
4
Посетители должны получать информацию, потенциально связанную с безопасностью, из источника, который может быть обновлен надлежащим образом, а не с вопросов, закрытых для новых ответов. Я удаляю ответы на этот дубликат, чтобы посетители читали ответы на открытый вопрос. (Если этот вопрос когда-нибудь будет вновь открыт, ответы будут восстановлены.)
Джереми Бэнкс
6
@JeremyBanks Нигде в вопросе не говорится о криптографически безопасном пароле. Для некоторых людей /dev/randomдостаточно использовать ответы , так как вопрос не требует « безопасного » пароля (и его не следует редактировать, чтобы он содержал его, так как это изменило бы значение исходного вопроса). Хотя я полностью за безопасность, я думаю, что эта ковровая бомба не была полностью продумана. Как и при использовании mysql_*, ответы все еще действительны, но должны быть помечены как небезопасные. Возможно, это то, что SO необходимо включить в качестве дополнительного программного обеспечения - возможность предупреждать о небезопасном коде?
Джимбо
6
@JeremyBanks Не могли бы вы восстановить ответы на этот вопрос? То, что это дубликат, не означает, что ответы неправильные (я случайно проголосовал за повторное открытие, я согласен, что это дубликат). Нет смысла удалять ответы. Попробуйте вместо этого удалить этот вопрос и перенести ответы на другой вопрос (я уже видел это ранее).
Нафтали ака Нил
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()
Sorry-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,random_int() чтобы вы могли использовать новый API до выхода PHP 7. Использование нашего random_int()polyfill, вероятно, безопаснее, чем написание собственной реализации.

С помощью надежного генератора случайных целых чисел создать безопасную случайную строку проще, чем 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;
}
Скотт Аркишевский
источник
2
RandomLib не обновлялся более двух лет. Использование его в недавней сборке PHP (в моем случае 7.1.25) выдает предупреждения об устаревании для различных mcrypt_*функций. В потоке проблем я вижу, что вы разветвили библиотеку из-за того, что не смогли удержать @ircmaxell, но ваш форк говорит, что сборка не удалась на Трэвисе. Хотели бы вы обновить этот ответ (который все еще довольно высок в Google)?
Янус Бах Жакет
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!

user3260409
источник
13
Если вам нужен пароль, состоящий
willbradley,
@ زياد Говорит кто? Если бы в генераторе использовались 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 вы можете определить, сколько символов будет создано.

BSQ
источник
21
Хорошо, хотя при таком подходе вы не получите повторяющихся символов, что может быть нежелательно.
Хобо
11
Эта функция ужасна для генерации длинных паролей. Во-первых, если $ length длиннее строки $ chars, вы не получите строку, если длина введенной вами длины равна длине строки chars. Кроме того, вам гарантирован только 1 из каждого символа без дубликатов. Это также не гарантирует использование заглавной буквы или цифры, что довольно часто является обязательным требованием (если, конечно, ваша длина больше 26 из-за предыдущей ошибки)
Programster
Как насчет этого @Programster и @Hobo? substr(str_shuffle(str_repeat($chars,$length)),0,$length);
Шарль-Эдуард Кост
@ Charles-EdouardCoste, кажется, работает достаточно хорошо (особенно если вы добавите несколько специальных символов). Хотя это все еще не гарантирует, по крайней мере, один из каждого типа символов. Единственное, что меня беспокоит, - это повторение всего набора символов по длине желаемого пароля, но это гарантирует, что символы в сгенерированном пароле не должны быть уникальными и не окажут заметного влияния на производительность за одно использование.
Programster
Я согласен. Вероятно, лучше не выбирать алгоритм по количеству строк. Кстати, если основная цель - просто создать временный пароль при создании нового пользователя на веб-сайте, я думаю, это будет соответствовать потребностям.
Шарль-Эдуард Кост
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;
}
PeeHaa
источник
12
не используйте mt_randдля генерации пароля.
CodesInChaos
2
@CodesInChaos это лучше, чем rand (), который используется в приведенном выше примере. openssl_random_pseudo_bytes () является предпочтительным в соответствии с руководством по PHP.
Willbradley
4
@willbradley Качество семян столь же плохое mt_rand, поэтому оно по-прежнему непригодно для использования в целях безопасности.
CodesInChaos
2
вы видите, это то, что меня раздражает + ChaosInCodes. Вы не смотрели на вопрос, вы просто сделали несколько общих утверждений, повторяющих множество плохо удерживаемых убеждений. Короче говоря: правильный совет для совершенно другого вопроса. Случайные пароли в порядке. Они, вероятно, только "х". Честно говоря, если вы разрабатываете свою систему без временных блокировок и обнаружения DOS и «х пытается потом -> заблокировано», то вы делаете это неправильно. Невозможно угадать пароль mt_rand с такими мерами. И наоборот, использование mt_rand не облегчит взлом пароля. Это просто не будет.
Мистер Хилис,
1
Я бы не использовал \ in$chars
CONvid19
36

В одной строке:

substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') , 0 , 10 )
Sandra
источник
11
Это предотвращает повторное использование одних и тех же букв, поскольку они просто перемешиваются, но не встречаются более одного раза.
nickdnk
8
Излишне говорить, что никто не должен оптимизировать функцию генерации паролей на основе количества строк. Даже если этот используемый ГСЧ был безопасным (это не так), избегание повторяющихся символов при генерации 10-символьного пароля приводит к уменьшению от ~ 52 бит энтропии до ~ 50 бит энтропии (~ в 4 раза быстрее взломать). Если вы увеличите это значение до 20 символов, неповторение приведет к снижению с ~ 103 бит до ~ 94 бит (в 512 раз быстрее взломать).
Джереми Бэнкс
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ответы неправильными.
Цербр
8
@Cerbrus: Конечно, этот ответ не дает rand()неправильных ответов . Они неверны сами по себе!
Дедупликатор
14

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

Однако randне подходит случайная функция для этой цели. Его вывод можно легко предсказать, так как он неявно засеян текущим временем. Дополнительно,rand не является криптографически безопасным; поэтому относительно легко определить его внутреннее состояние по выходным данным.

Вместо этого читайте, /dev/urandomчтобы получить криптографически случайные данные.

phihag
источник
14

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

  • Меньшее пространство символов, чем вы хотели, так что или грубое принуждение проще, или пароль должен быть длиннее для той же энтропии
  • RNG , не считается криптографический безопасными
  • требование для какой-то сторонней библиотеки, и я подумал, что было бы интересно показать, что нужно сделать, чтобы сделать это самостоятельно

Этот ответ обойдет count/strlenпроблему, поскольку безопасность сгенерированного пароля, по крайней мере, ИМХО, выходит за рамки того, как вы туда попали. Я также собираюсь предположить, 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 будут этими «нежелательными» символами, так что простое отбрасывание этих символов приведет к тому, что строка будет не короче, чем хотел OP. Тогда мы можем просто обрезать его, чтобы получить точную длину:

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

Если вы генерируете более длинные пароли, символ заполнения =формирует все меньшую и меньшую пропорцию промежуточного результата, чтобы вы могли реализовать более узкий подход, если проблема заключается в опустошении пула энтропии, используемого для PRNG.

jeteon
источник
1
Спасибо за это дополнение. Ни один из существующих ответов не отметил, что openssl_random_pseudo_bytesможет дать слабый результат. Я не осознавал, что это так.
Джереми Бэнкс
12

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

например. e0m6ngefmj4

РЕДАКТИРОВАТЬ

Как я упоминал в комментариях, длина означает, что атаки методом "грубой силы" будут работать лучше, чем атаки по времени, поэтому не стоит беспокоиться о том, "насколько безопасен генератор случайных чисел". Безопасность, особенно для этого варианта использования, должна дополнять удобство использования, поэтому приведенное выше решение на самом деле достаточно хорошо для требуемой проблемы.

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

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

function secureId($length = 32) {

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

        error_log("Missing support for openssl_random_pseudo_bytes");

        $pr_bits = '';

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

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

        return base64urlEncode($pr_bits);
    }
}
srcspider
источник
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. Для чего-то, что не похоже на hex, попробуйте это:

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);
        }
    
    }
    
    ?>
WAZ
источник
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);
monrejames
источник
1
//define a function. It is only 3 lines!   
function generateRandomPassword($length = 5){
    $chars = "0123456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
    return substr(str_shuffle($chars),0,$length);
}

//usage
echo generateRandomPassword(5); //random password legth: 5
echo generateRandomPassword(6); //random password legth: 6
echo generateRandomPassword(7); //random password legth: 7
hakiko
источник
Это на самом деле (очень?) Неправильно. Он фактически использует каждый символ из алфавита только один раз, таким образом, значительно сокращает пространство всех возможных значений (относящихся к взлому).
Радослав Бодо
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;
}
Behiry
источник
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);
}
Себастьян Сулински
источник