PHP에서 임의의 비밀번호 생성


190

PHP에서 임의의 암호를 생성하려고합니다.

그러나 나는 모든 'a'를 얻었고 반환 유형은 배열 유형이며 문자열이되고 싶습니다. 코드를 수정하는 방법에 대한 아이디어가 있습니까?

감사.

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

9
답은 보안 난수 생성기 를 사용하지 않으므로 암호를 원합니다.
Scott Arciszewski

4
방문자는 새로운 답변으로 마감 된 질문이 아니라 올바르게 업데이트 할 수있는 출처에서 잠재적으로 보안 관련 정보를 가져와야합니다. 방문자가 공개 질문에 대한 답변을 대신 읽을 수 있도록이 중복에 대한 답변을 삭제하고 있습니다. (이 질문이 다시 열리면 답변이 삭제되지 않습니다.)
Jeremy Banks

6
@JeremyBanks 어디에도 암호로 안전한 암호가 필요하다는 질문 이 없습니다. 어떤 사람들 /dev/random에게는 질문에 " 안전한 "암호를 요구하지 않기 때문에 사용하는 답변 으로 충분 합니다 (원래 질문의 의미를 바꿀 수 있으므로 암호를 포함하도록 편집해서는 안됩니다). 나는 안전을 위해 전부이지만,이 카펫 폭탄은 완전히 생각되지 않았다고 생각합니다. 를 사용 mysql_*하는 것처럼 답변은 여전히 ​​유효하지만 안전하지 않은 것으로 표시해야합니다. 아마도 이것은 안전하지 않은 코드 에 대해 경고 하는 기능인 SO를 추가 소프트웨어로 포함시켜야 할 것 입니까?
Jimbo

6
@JeremyBanks이 질문에 대한 답변을 복원 해 주시겠습니까? 그것이 중복이기 때문에 대답이 잘못되었다는 것을 의미하지는 않습니다 (우연히 다시 열기로 투표했다면 중복임을 동의합니다). 답변을 삭제하는 것은 의미가 없습니다. 대신이 질문을 제거하고 다른 질문으로 답변을 마이그레이션하십시오 (이전에는 본 적이 있음).
Naftali 일명 Neal

7
@JeremyBanks 다시 열지 않으려면 잠그십시오. 그렇지 않으면 99 %의 사람들이 그것을 다시 열고 전체 혼란을 일으킬 것입니다. 개인적으로 나는 그렇게 높은 점수를 얻은 답변을 삭제하는 것에 완전히 동의하지 않지만, 이것을 극복 할 수는 없습니다
Shadow Wizard is Ear For You

답변:


258

보안 경고 : rand()암호로 안전한 의사 난수 생성기가 아닙니다. PHP에서 암호로 안전한 의사 난수 문자열생성하려면 다른 곳을 찾으십시오 .

이것을 시도하십시오 ( 문자열은 항상 이므로 strlen대신 대신 사용하십시오 ).countcount1

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].
Matthew

33
rand를 사용하여 비밀번호 를 생성 하는 것은 정말 나쁜 생각입니다. 안전한 PRNG가 아닙니다. (그리고 더 나은하거나하지 않습니다)mt_rand
CodesInChaos

19
문제는 비밀번호 생성에 관한 것 입니다. 암호를 생성하는 코드는 안전한 임의의 숫자를 사용해야합니다.
코드 InChaos

10
이이 같은 이유로 하지 질문에 대해 때문에 중복 질문이 대답은 잘못된 암호를 생성 하고 있지 임의의 문자열을 . 이 답변은 암호 생성에 대한 매우 안전하지 않은 접근 방식을 제공합니다. 아래 @ user3260409의 답변을 openssl_random_pseudo_bytes()대신 사용하십시오. 대신에 사용됩니다rand()
Sorry-Im-a-N00b

35
프로덕션에서 안전하지 않은 코드 보았고 소스에서 중지하고 싶습니다. 당신이 필요해 암호를 암호 학적으로 안전한 난수를.
Scott Arciszewski

122

TL; DR :

설명:

비밀번호를 생성하고 있으므로 생성 한 비밀번호를 예측할 수 없는지 확인해야하며 구현 시이 특성이 존재하는지 확인하는 유일한 방법은 암호로 안전한 의사 난수 생성기 를 사용하는 것입니다. 시이 (CSPRNG) 입니다.

임의의 문자열의 일반적인 경우 CSPRNG에 대한 요구 사항을 완화 할 수 있지만 보안이 관련된 경우에는 불가능합니다.

PHP에서 암호 생성에 대한 간단하고 안전하며 정확한 답변은 RandomLib 을 사용하는 것입니다 하고 바퀴를 재발 명하지 않는 것입니다. 이 라이브러리는 업계 보안 전문가 및 본인에 의해 감사되었습니다.

자체 솔루션 개발을 선호하는 개발자에게는 PHP 7.0.0이 random_int()이러한 목적으로 제공 됩니다. 아직 PHP 5.x를 사용하고 있다면 PHP 5 폴리 필을random_int() 작성하여 PHP 7이 출시되기 전에 새로운 API를 사용할 수 있습니다. 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은 2 년 이상 업데이트되지 않았습니다. 최근 PHP 빌드 (제 경우 7.1.25)에서 사용하면 다양한 mcrypt_*기능에 대한 지원 중단 경고가 발생 합니다. 나는에 볼 수있는 문제 스레드 는 것을 라이브러리 갈래 @ircmaxell의 보류를 얻을 수없는 때문에,하지만 포크 트래비스의 '실패한 빌드'말한다. 이 답변을 업데이트 하시겠습니까? (Google에서 여전히 높게 표시됨)?
Janus Bahs Jacquet

1
잘 잡아! 제거해야합니다.
Scott Arciszewski

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
대문자, 소문자 및 숫자로 된 암호를 원하면 다음을 시도하십시오. gist.github.com/zyphlar/7217f566fc83a9633959
willbradley

@ زياد 누가 말합니다? 생성기가 7 비트 바이트를 사용하는 경우 동의하지만 openssl_random_pseudo_bytes()강력한 전체 이진 바이트 임의 생성기이므로 더 이상 셔플 링이 필요하지 않습니다. 또한 여러 암호화 방법을 스태킹하면 더 임의의 항목이 생성된다고 가정하는 것이 위험하다는 점을 알 수 있습니다. 경우에 따라 해싱 충돌이 누적되어 실제로는 정반대 일 수도 있습니다.
Havenard

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 문자열보다 길면 입력 한 길이만큼 문자열을받지 않고 chars 문자열의 길이를받습니다. 또한 중복되지 않은 각 문자 중 하나만 보장됩니다. 또한 대문자 또는 숫자의 사용을 보장하지는 않습니다 (이전 결함으로 인해 길이가 26 이상인 경우는 제외)
Programster

이 @Programster와 @Hobo는 어떻습니까? substr(str_shuffle(str_repeat($chars,$length)),0,$length);
Charles-Édouard Coste

@ 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비밀번호를 생성하는 데 사용하지 마십시오 .
코드 InChaos

2
@CodesInChaos 위의 예제에서 사용하는 rand ()보다 낫습니다. openssl_random_pseudo_bytes ()는 PHP 매뉴얼에 따라 선호됩니다.
willbradley

4
@willbradley 씨앗의 품질은 나쁘기 mt_rand때문에 보안 용도로는 여전히 적합하지 않습니다.
코드 InChaos

2
당신은 이것이 나를 귀찮게하는 것을 보았습니다 + ChaosInCodes. 당신은 그 질문을 보지 않았고, 당신은 몇 가지 일반적인 진술을 불충분 한 신념으로 반복했습니다. 간단히 말해서 완전히 다른 질문에 대한 올바른 조언입니다. 임의의 암호는 괜찮습니다. 아마도 "x"만 사용합니다. 정직하게 시간 초과 잠금 및 DOS 감지없이 시스템을 설계하고 "x는 다음에 시도-> 잠김"상태이면 잘못하고있는 것입니다. 그러한 조치를 취한 mt_rand 비밀번호를 추측하는 것은 불가능합니다. 반대로 mt_rand를 사용한다고해서 암호를 무차별하게하는 것은 쉽지 않습니다. 그냥하지 않습니다.
Mr Heelis

1
나는 \ in을 사용하지 않을 것이다$chars
CONvid19

36

한 줄로 :

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

11
이렇게하면 글자가 뒤섞 일 때와 동일한 문자를 다시 사용할 수 없지만 두 번 이상 나타나지 않습니다.
nickdnk

8
말할 것도없이, 아무도 라인 수에 기초하여 암호 생성 기능을 최적화해서는 안됩니다. 사용 된 RNG가 안전하더라도 (그렇지 않음) 10 자 암호를 생성하는 동안 반복되는 문자를 피하면 ~ 52 비트의 엔트로피에서 ~ 50 비트의 엔트로피 (크랙보다 4 배 빠름)가 줄어 듭니다. 이 문자를 20 자로 확장하면 비 반복으로 인해 ~ 103 비트에서 ~ 94 비트로 줄어 듭니다 (~ 512 배 더 빨리 크랙).
Jeremy Banks

1
이 방법은 Enigma 코드 Lol 의 결함을 생각 나게합니다.
hatef

4
substr(str_shuffle(str_repeat($chars,$length)),0,$length); 엔트로피 복원
Charles-Édouard Coste

27

가장 좋은 방법은 ircmaxellRandomLib 라이브러리입니다 입니다.

사용 예 :

$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().
Scott Arciszewski

1
가장 안전한 답변 일 수는 있지만 (어떻게 비교하는지 확실 random_bytes하지는 않지만) rand대답이 잘못 되지는 않습니다.
Cerbrus


8
@Cerbrus :이 답변이 rand()잘못된 답변을하지는 않습니다 . 그들은 모두 스스로 틀렸다!
중복 제거기

14

상수가 strlen($alphabet)아닌 countalphabet(를 'alphabet') 원합니다 .

그러나이 rand목적에 적합한 임의 함수는 아닙니다. 현재 시간에 암시 적으로 시드되므로 출력을 쉽게 예측할 수 있습니다. 또한 rand암호화 적으로 안전하지 않습니다. 따라서 출력에서 ​​내부 상태를 결정하는 것이 상대적으로 쉽습니다.

대신, /dev/urandom암호로 임의의 데이터를 얻으려면을 읽으십시오 .


14

기존 답변 중 일부가 가깝지만 다음 중 하나를 가지고 있기 때문에 답변을 게시하려고합니다.

  • 같은 엔트로피에 대해 무차별 대입이 더 쉬워 지거나 암호가 더 길어 지도록 원하는 것보다 작은 문자 공간
  • RNG 암호 학적으로 안전한 것으로 간주되지 않는다
  • 일부 타사 라이브러리에 대한 요구 사항이며 직접 수행하는 데 필요한 내용을 보여주는 것이 흥미로울 수 있다고 생각했습니다.

이 답변은 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 인코딩으로 인해 바이트 문자열보다 길이가 3 분의 1 이상 큰 문자열이 생성되기 때문입니다. $n그렇지 않으면 4 자에서 3 자까지의 길이가 길어 지므로 결과는 정확합니다 . 여분의 문자는 주로 패딩 문자이기 때문에 =어떤 이유로 든 암호가 정확한 길이라는 제약이 있다면 원하는 길이로자를 수 있습니다. 이는 주어진 $n암호에 대해 모든 암호가 동일한 수로 끝나기 때문에 결과 암호에 액세스 한 공격자가 추측 할 수있는 문자가 최대 2 개이기 때문입니다.


추가 크레딧을 위해 OP의 질문에서와 같이 정확한 사양을 충족하려면 조금 더 많은 작업을 수행해야합니다. 여기서는 기본 변환 방식을 포기하고 빠르고 더러운 방식으로 진행하겠습니다. 62 개 항목의 긴 알파벳 때문에 결과에 사용되는 것보다 더 많은 임의성을 생성해야합니다.

결과의 추가 문자의 경우 결과 문자열에서 단순히 문자를 버릴 수 있습니다. 바이트 열에서 8 바이트로 시작하면 base64 문자의 최대 약 25 %가이 "바람직하지 않은"문자가됩니다. 따라서이 문자를 버림으로써 원하는 OP보다 짧게 문자열을 만들 수 있습니다. 그런 다음 간단히 잘라서 정확한 길이로 얻을 수 있습니다.

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

더 긴 비밀번호를 생성하는 경우, 패딩 문자 =는 중간 결과의 더 작은 비율을 형성하므로 PRNG에 사용 된 엔트로피 풀을 비우는 것이 문제가 될 경우 더 적은 접근 방식을 구현할 수 있습니다.


1
이 추가에 감사드립니다. 기존 답변들 중 어느 것도 openssl_random_pseudo_bytes약한 결과 를 낼 수 있다고 언급하지 않았습니다 . 나는 그것이 사실인지 몰랐다.
Jeremy Banks

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

1
추신-이것은 PHP입니다-\를 사용하여 전역 네임 스페이스를 나타냅니다.
밥 그레고르

uniqid는 암호화 적으로 안전하지 않습니다. 대신 rand ()를 사용하십시오. base_convert (rand (78364164096, 2821109907455), 10, 36);
Benubird

7
PHP 매뉴얼에 따르면 @Benubird rand ()도 암호로 안전하지 않습니다. 매뉴얼에서는 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
엔트로피의 128 비트 암호화 해시로 압축하기 위해 1024 바이트를 읽는 것은 약간 낭비입니다. 또한 fread()기본적으로 8192 바이트로 버퍼링되므로 항상 /dev/urandom주어진 코드로 많은 것을 읽을 것입니다 . 이것은 Windows에서도 작동하지 않습니다. 그래도 CSPRNG를 사용하는 것이 좋습니다.
Scott Arciszewski


7

med-strong password 12 길이를 생성하려면이 간단한 코드를 사용하십시오.

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

이것은 실제로 (매우?) 잘못되었습니다. 실제로 알파벳의 모든 문자를 한 번만 사용하므로 가능한 모든 값의 공간을 크게 줄입니다 (균열과 관련 있음).
Radoslav 보도

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 Digit Pass가 필요하다고 가정 해 봅시다.

echo generatePassword(10);  

출력 예 :

, IZCQ_IV \ 7

@wlqsfhT (d

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 이 페이지의 다른 답변을 기반으로합니다.

이 답변은 16 진 문자 만 생성 0-9,a-f합니다. 16 진수가 아닌 것으로 보이는 경우 다음을 시도하십시오.

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

이것은 실제로 (매우?) 잘못되었습니다. 실제로 알파벳의 모든 문자를 한 번만 사용하므로 가능한 모든 값의 공간을 크게 줄입니다 (균열과 관련 있음).
Radoslav 보도

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);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.