Php rastgele bir şifre oluşturma


190

Ben php rastgele bir şifre oluşturmak için çalışıyorum.

Ancak tüm 'a alıyorum ve dönüş türü türü dizi ve bir dize olmasını istiyorum. Kodun nasıl düzeltileceği hakkında herhangi bir fikriniz var mı?

Teşekkürler.

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

9
Cevapların hiçbiri parola için güvenli bir rasgele sayı üreteci kullanmaz .
Scott Arciszewski

4
Ziyaretçiler, yeni yanıtlara kapalı bir soru değil, düzgün bir şekilde güncellenebilen bir kaynaktan güvenlikle ilgili potansiyel bilgiler almalıdır. Ziyaretçilerin açık soruya verilen cevapları okuyabilmesi için bu kopyaya verilen yanıtları siliyorum. (Bu soru yeniden açılırsa, yanıtlar geri alınacaktır.)
Jeremy Banks

6
@JeremyBanks Soru hiçbir yerde kriptografik olarak güvenli bir parola gerektiğini belirtmiyor . Bazı kişiler için, /dev/randomsoru " güvenli " bir şifre istemediğinden (ve orijinal sorunun anlamını değiştireceği için bu parolayı içerecek şekilde düzenlenmemelidir) kullanarak yanıtlar yeterlidir . Her ne kadar güvenlik için olsam da, bu halı bombasının tam olarak düşünülmediğini düşünüyorum. Kullanmak mysql_*gibi, cevaplar hala geçerlidir, ancak güvensiz olarak işaretlenmelidir. Belki de bu, SO'nun ekstra bir yazılım olarak içermesi gereken bir şeydir - güvensiz kodu uyarma yeteneği ?
Jimbo

6
@JeremyBanks Lütfen bu sorunun yanıtlarını tekrar eski haline getirebilir misiniz? Sadece bir kopya olduğu için cevapların yanlış olduğu anlamına gelmez (yanlışlıkla tekrar açmak için oy verdim, bunun bir kopya olduğunu kabul ediyorum). Cevapları silmek mantıklı değil, bunun yerine bu soruyu kaldırmayı ve cevapları diğer soruya taşımayı düşünün (daha önce yapıldığını gördüm).
Naftali aka Neal

7
@JeremyBanks Bir şeyin yeniden açılmamasını istiyorsanız kilitleyin. Aksi halde,% 99 kişi yeniden açacak ve bütün bir karışıklık yaratacaktır. Şahsen ben de böyle yüksek puanlı cevapları silmeye tamamen katılmıyorum, ama bununla savaşamıyorum
Gölge Sihirbazı Kulak İçin

Yanıtlar:


258

Güvenlik uyarısı : rand()kriptografik olarak güvenli bir sahte numara üreteci değildir. PHP'de kriptografik olarak güvenli bir sahte anahtar dizesi oluşturmak için başka bir yere bakın .

Bunu deneyin ( bir dizede her zaman olduğu için strlenyerine kullanın ):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
}

Demo: http://codepad.org/UL8k4aYK


24
Kullanımı daha basit görünüyor $pass .= $alphabet[$n].
Matthew

33
Rand kullanarak şifre oluşturmak gerçekten kötü bir fikir. Güvenli bir PRNG değil. (ve hayır da daha iyi değil)mt_rand
CodesInChaos

19
Soru, bir şifre oluşturmakla ilgilidir . Bir şifre oluşturmak için kodun açıkça güvenli rasgele sayılar kullanması gerekir.
CodesInChaos

10
Bu gibi Aynı nedenle değil soru hakkında beri yinelenen bir soru, bu cevap yanlıştır bir şifre üreten ve olmayan bir rastgele dize . Bu cevap bir şifre oluşturmak için son derece güvensiz bir yaklaşım sağlar. Lütfen aşağıdaki openssl_random_pseudo_bytes()yerine kullanılan @ user3260409 yanıtını kullanınrand()
Üzgünüz-Im-a-N00b

35
Güvensiz kodunuzu üretimde gördüm ve kaynağında durdurmak istiyorum. Sen İHTİYACINIZ şifreler için kriptografik rastgeleliğine.
Scott Arciszewski

122

TL; DR:

  • Kullanımı random_int()ve random_str()aşağıda verilmiştir.
  • Eğer yoksa random_int(), random_compat kullanın .

Açıklama:

Bir parola oluşturduğunuz için, oluşturduğunuz parolanın öngörülemez olduğundan emin olmanız gerekir ve bu özelliğin uygulamanızda bulunmasını sağlamanın tek yolu kriptografik olarak güvenli bir sözde sayı üreteci (CSPRNG) kullanmaktır.

CSPRNG gereksinimi, rasgele dizelerin genel durumu için gevşetilebilir, ancak güvenlik söz konusu olduğunda değil.

PHP'de şifre oluşturmanın basit, güvenli ve doğru cevabı RandomLib kullanmak ve tekerleği yeniden icat etmemek. Bu kütüphane kendimin yanı sıra endüstri güvenliği uzmanları tarafından denetlenmiştir.

Kendi çözümünüzü icat etmeyi tercih eden geliştiriciler için, PHP 7.0.0 random_int()bu amacı sağlayacaktır . Hala PHP 5.x kullanıyorsanız, için bir PHP 5 çoklu dolgusu yazdıkrandom_int() kullanıyorsanız, PHP 7 yayınlanmadan önce yeni API'yi kullanabilmeniz . random_int()Çoklu dolgumuzu kullanmak muhtemelen kendi uygulamanızı yazmaktan daha güvenlidir.

Eldeki güvenli bir rastgele tamsayı oluşturucusuyla, güvenli bir rastgele dize oluşturmak pastadan daha kolaydır:

<?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 iki yıldan fazla bir süredir güncellenmemiştir. Yeni bir PHP derlemesinde (benim durumumda 7.1.25) kullanılması, çeşitli mcrypt_*işlevler için kullanımdan kaldırma uyarıları atar . Ben görebileceğiniz bir sorun iplik sen olduğunu kütüphaneyi çatallı @ircmaxell bir tutmak mümkün olmayan nedeniyle ancak çatal Travis üzerinde 'başarısız inşa' diyor. Bu yanıtı güncellemek ister misiniz (Google'da hâlâ oldukça yüksek görünüyor)?
Janus Bahs Jacquet

1
İyi yakalama! Kaldırılması gerekiyor.
Scott Arciszewski

113

Parolanızı belirli bir şekilde oluşturmaya çalıştığınızı biliyorum, ancak bu yönteme de bakmak isteyebilirsiniz ...

$bytes = openssl_random_pseudo_bytes(2);

$pwd = bin2hex($bytes);

Php.net sitesinden alınır ve openssl_random_pseudo_bytes işlevine koyduğunuz sayının iki katı uzunluğunda bir dize oluşturur. Yani yukarıdaki 4 karakter uzunluğunda bir şifre oluşturacaktır.

Kısacası...

$pwd = bin2hex(openssl_random_pseudo_bytes(4));

8 karakter uzunluğunda bir şifre oluşturur.

Bununla birlikte, parolanın yalnızca 0-9 arasındaki sayıları ve küçük büyük harfler af olduğunu unutmayın!


13
Büyük harf, küçük harf ve rakam içeren bir şifre istiyorsanız şunu deneyin: gist.github.com/zyphlar/7217f566fc83a9633959
willbradley

@ زياد Kim diyor? Jeneratör 7 bit bayt kullanıyor olsaydı, seninle aynı fikirde olurdum, ancak openssl_random_pseudo_bytes()güçlü bir tam ikili bayt rasgelelik üretecidir ve daha fazla karıştırmaya gerek yoktur. Ayrıca, birden fazla şifreleme yönteminin istiflenmesinin daha rastgele bir şey yapacağını varsaymanın tehlikeli olduğunu belirtme şansım olacak, bazı durumlarda karma çarpışmaların birikmesi nedeniyle tam tersi olabilir.
Havenard

56

2 satırlı küçük kod .

demo: http://codepad.org/5rHMHwnH

function rand_string( $length ) {

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

}

echo rand_string(8);

rand_string ile ne kadar karakter oluşturacağınızı tanımlayabilirsiniz.


21
Güzel, ancak bu yaklaşımı kullanarak tekrarlanan karakterler alamayacaksınız, bu istenmeyen bir durum olabilir.
Hobo

11
Bu işlev uzun parolalar oluşturmak için korkunçtur. İlk olarak, $ uzunluğu $ chars dizesinden daha uzunsa, girdiğiniz uzunluk kadar bir dize almazsınız, ancak chars dizesinin uzunluğu. Ayrıca, her karakterin yalnızca 1 tanesinin kopyaları olmadan garanti edilir. Ayrıca, büyük harf veya sayı gerektiren bir sayı (genellikle önceki hata nedeniyle uzunluğunuz 26'dan fazla ise) hariç - garanti edilmez
Programster

Peki ya @Programster ve @Hobo? substr(str_shuffle(str_repeat($chars,$length)),0,$length);
Charles-Édouard Coste

@ Charles-EdouardCoste yeterince iyi çalışıyor gibi görünüyor (özellikle bazı özel karakterleri atarsanız). Yine de her karakter tipinden en az birini garanti etmemektedir . Beni rahatsız eden tek şey, istenen parolanın uzunluğuna göre tüm karakter setini tekrarlamaktır, ancak oluşturulan paroladaki karakterlerin benzersiz olması gerekmez ve tek bir kullanımda fark edilir bir performans etkisi yoktur.
Programcı

Hemfikirim. Satır sayısı üzerinde bir algoritma seçmemek daha iyidir. Bu arada, asıl amaç sadece bir web sitesinde yeni bir kullanıcı oluştururken geçici bir şifre oluşturmaksa, sanırım bu ihtiyaçları karşılayacaktır.
Charles-Édouard Coste

40

PHP7 kullanıyorsanız bu random_int()işlevi kullanabilirsiniz :

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

Aşağıdaki eski cevap:

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şifre oluşturmak için kullanmayın .
Kodlar

2
@CodesInChaos, yukarıdaki örneğin kullandığı rand () 'den daha iyidir. PHP kılavuzuna göre openssl_random_pseudo_bytes () tercih edilir.
willbradley

4
@willbradley Tohumun kalitesi aynı derecede kötüdür mt_rand, bu nedenle güvenlik kullanımı için hala uygun değildir.
CodesInChaos

2
beni rahatsız eden şey budur + ChaosInCodes. Soruya bakmadınız, az sayıda kötü inanç yükünü tekrarlayan bazı genel ifadeler yaptınız. Kısacası: tamamen farklı bir soru için doğru tavsiye. Rastgele şifreler uygundur. Muhtemelen yalnızca "x" kullanımıdır. Son derece dürüst sisteminizi zamanlanmış kilitleme ve DOS algılama ve "x sonra çalışır -> kilitli" olmadan tasarlıyorsanız, o zaman yanlış yapıyorsunuz. Bu tür önlemlerin alındığı bir mt_rand şifresini tahmin etmek imkansızdır. Bunun tersine mt_rand kullanmak parolayı kaba zorlamayı kolaylaştırmaz. Sadece olmayacak.
Bay Heelis

1
\ $chars
İn

36

Bir satırda:

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

11
Bu, aynı harflerin sadece karıştırıldığı, ancak bir kereden fazla oluşmadığı şekilde yeniden kullanılmasını önler.
nickdnk

8
Söylemeye gerek yok, hiç kimse şifre oluşturma işlevini satır sayısına göre optimize etmemelidir. Kullanılan RNG güvenli olsa bile (değil), 10 karakterlik bir parola oluştururken tekrarlanan karakterlerden kaçınmak sizi ~ 52 bit entropiden ~ 50 bit entropiye (~ 4x daha hızlı çatlamak) indirir. Bunu 20 karaktere kadar genişletirseniz, tekrarlama sizi ~ 103 bit'ten ~ 94 bite (çatlamak için ~ 512x daha hızlı) indirir.
Jeremy Banks

1
Bu yöntem hatırlatıyor Enigma kodunu kusur Lol
hatef

4
substr(str_shuffle(str_repeat($chars,$length)),0,$length); Entropi restore edildi
Charles-Édouard Coste

27

En iyi bahsiniz ircmaxell tarafından RandomLib kütüphanesi .

Kullanım örneği:

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

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

Normal rastgele işlevlerden daha güçlü rasgele dizeler üretir shuffle()ve rand()(genellikle parolalar, tuzlar ve anahtarlar gibi hassas bilgiler için istediğiniz şeydir).


4
Bu doğru cevap. rand()Veya kullanmayın mt_rand().
Scott Arciszewski

1
En güvenli cevap olabilir (nasıl karşılaştırıldığından emin değil random_bytes), ancak bu randcevapları yanlış yapmaz .
Cerbrus


8
@Cerbrus: Elbette bu cevap rand()yanlış kullanarak cevap vermiyor . Hepsi kendi başlarına yanlış!
Deduplicator

14

İstediğiniz strlen($alphabet), countsabiti değil alphabet('alphabet' ).

Bununla birlikte, randbu amaç için uygun bir rastgele fonksiyon değildir. Çıktısı, şimdiki zamanla örtülü olarak ekildiği için kolayca tahmin edilebilir. Bunlara ek olarak,rand kriptografik olarak güvenli değildir; bu nedenle dahili durumunu çıktıdan belirlemek nispeten kolaydır.

Bunun yerine, /dev/urandomkriptografik olarak rasgele veri almak için okuyun .


14

Bir cevap göndereceğim çünkü mevcut cevaplardan bazıları yakın ama şunlardan birine sahip:

  • kaba kuvvet zorlamanın daha kolay olması veya aynı entropi için parolanın daha uzun olması için istediğinizden daha küçük bir karakter alanı
  • şifreli olarak güvenli kabul edilmeyen bir RNG
  • bazı üçüncü taraf kütüphaneleri için bir gereklilik ve bunu kendiniz yapmak için ne gerektiğini göstermenin ilginç olabileceğini düşündüm

Bu cevap count/strlen, oluşturulan parolanın güvenliği, en azından IMHO, oraya nasıl ulaştığınızı aştığından sorunu ortadan kaldıracaktır . Ben de PHP> 5.3.0 olduğunu varsayacağım.

Sorunu kurucu parçalara ayıralım:

  1. rasgele veri almak için güvenli bir rasgelelik kaynağı kullanın
  2. bu verileri kullanın ve bazı yazdırılabilir dize olarak temsil edin

İlk kısım için PHP> 5.3.0 fonksiyonu sağlar openssl_random_pseudo_bytes. Çoğu sistem kriptografik olarak güçlü bir algoritma kullanırken, bir paketleyici kullanmamız için kontrol etmeniz gerektiğini unutmayın:

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

İkinci kısım için, base64_encodebir bayt dizesi aldığından ve orijinal soruda belirtilene çok yakın bir alfabeye sahip bir dizi karakter üreteceğinden kullanacağız. Biz sahip aldırmadı ise +, /ve =karakterler son dizede görünür ve biz en azından bir sonuç istiyorum $nkarakterden, biz sadece kullanabilirsiniz:

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

3/4Faktör nedeniyle base64 bayt dize daha az üçte daha büyük bir uzunluğa sahip olan bir dizede sonuçları kodlayan gerçeği etmektir. Sonuç, $naksi takdirde 4'ün katları ve 3 karaktere kadar daha uzun olması için kesin olur . Fazladan karakterler ağırlıklı olarak dolgu karakteri olduğundan =, bir nedenden dolayı parolanın tam bir uzunluk olduğu konusunda bir kısıtlamamız olsaydı, onu istediğimiz uzunlukta kısaltabiliriz. Bunun nedeni, özellikle $n, belirli bir şifre için tüm şifrelerin aynı sayı ile bitmesi ve sonuç şifresine erişimi olan bir saldırganın tahmin edilmesi gereken en az 2 karaktere sahip olmasıdır.


Ekstra kredi için, OP'nin sorusundaki spesifikasyonu karşılamak istersek, biraz daha fazla iş yapmamız gerekirdi. Burada temel dönüşüm yaklaşımından vazgeçeceğim ve hızlı ve kirli bir yaklaşımla gideceğim. Her ikisi de 62 giriş uzunluğundaki alfabe nedeniyle sonuçta kullanılacak olandan daha fazla rasgelelik üretmelidir.

Sonuçtaki ekstra karakterler için, bunları elde edilen dizeden atabiliriz. Bayt dizemizde 8 baytla başlarsak, base64 karakterlerinin yaklaşık% 25'i bu "istenmeyen" karakterler olur, böylece bu karakterleri atmak OP'den daha kısa olmayan bir dizeyle sonuçlanır. O zaman kesin uzunluğa inmek için kısaltabiliriz:

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

Daha uzun parolalar oluşturursanız, dolgu karakteri =ara sonucun daha küçük ve daha küçük bir oranını oluşturur, böylece PRNG için kullanılan entropi havuzunun boşaltılması endişe verici ise daha yalın bir yaklaşım uygulayabilirsiniz.


1
Bu ek için teşekkürler. Mevcut cevapların hiçbiri openssl_random_pseudo_byteszayıf bir sonuç verebileceğini belirtmedi . Durumun farkında değildim.
Jeremy Banks

12

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

Örneğin. e0m6ngefmj4

DÜZENLE

Yorumlarda bahsettiğim gibi, uzunluk kaba kuvvet saldırılarının ona karşı daha iyi çalışacağı anlamına geliyor, sonra zamanlama saldırıları, bu yüzden "rastgele jeneratörün ne kadar güvenli olduğu" konusunda endişelenmek gerçekten alakalı değil. Güvenlik, özellikle bu kullanım durumunda, kullanılabilirliği tamamlaması gerekir, böylece yukarıdaki çözüm aslında gerekli sorun için yeterince iyidir.

Ancak, jeton üretme gibi bir şey için, güvenli bir rastgele dize üreteci ararken (bazı insanların yanıtlara dayandığını varsaydığım gibi) bu cevabı tökezlemiş olmanız durumunda, bu tür kodlardan bir jeneratör şöyle görünecektir:

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 - bu PHP - sadece global ad alanını belirtmek için \ kullanarak.
Bob Gregor

Bunun dışında uniqid kriptografik olarak güvenli değildir. Bunun yerine rand () kullanın: base_convert (rand (78364164096, 2821109907455), 10, 36);
Benubird

7
PHP kılavuzuna göre @Benubird rand () şifreli olarak güvenli değildir. Kılavuz bunun yerine openssl_random_pseudo_bytes () önermektedir.
willbradley

Çoğu kullanım durumunda, özellikle saldırganın tam zamana erişemediği durumlarda, bu mükemmel bir şekilde iyidir ve hoş bir az ya da çok insan dostu "geçici" şifre üretir. Bunu aşırıya çıkarırsak, buradaki uzunluk çok daha zahmetlidir, o zaman rastgele sayıyı üretmek için hangi işlev kullanıldı.
srcspider

İlgilenenler için tamamen güvenli dizeler oluşturmak için bir örnek ekledim; ancak kullanıcılar için geçici şifreler oluştururken bunu kullanmanızı kesinlikle önermiyoruz. Güvenli sürümü kullanıyor olsa bile, uzunluk sorunu hala geçerlidir.
srcspider

9

Başka bir tane (sadece 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
Entropinin 128 bitlik şifreleme karmasına sıkıştırmak için 1024 bayt okumak biraz israftır. Ayrıca, fread()varsayılan olarak 8192 bayta arabelleğe alır, böylece her zaman /dev/urandomverilen kodu kullanarak bunları okuyabilirsiniz . Bu, Windows üzerinde de çalışmaz. Yine de bir CSPRNG kullanmak için şeref.
Scott Arciszewski

9

Biraz daha akıllı olmak:

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

buradan kontrol edin .


7

Orta güçlü parola 12 uzunluk oluşturmak için bu basit kodu kullanın

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

Bu aslında (çok?) Yanlış. Aslında alfabedeki her karakteri sadece bir kez kullanır, böylece olası tüm değerlerin (çatlama ile ilgili) alanını ciddi şekilde daraltır.
Radoslav Bodo

6

Büyük Harfler, Küçük Harfler, Rakam (lar) ve Özel Karakterlerle Bunu Deneyin

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
}

Diyelim ki 10 Haneli Geçişe ihtiyacımız var

echo generatePassword(10);  

Örnek Çıktılar:

, IZCQ_IV \ 7

@wlqsfhT (d

1! 8 + 1 \ 4 @ ud


randoldukça risk olabilir böylece fonksiyon aslında kriptografik kullanmadan bir şifre oluşturmak için güvenli değildir
jeteon

3

Hızlı olan. İstediğiniz buysa basit, temiz ve tutarlı format

$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

Bu, bu sayfadaki başka bir cevaba dayanmaktadır, https://stackoverflow.com/a/21498316/525649

Bu cevap sadece onaltılık karakterler oluşturur 0-9,a-f. Onaltılık gibi görünmeyen bir şey için şunu deneyin:

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 alfasayısal karakterlerin daha geniş bir dağılımını döndürür
  • rtrim=sonunda bazen kaldırır

Örnekler:

  • 32eFVfGDg891Be5e7293e54z1D23110M3ZU3FMjb30Z9a740Ej0jz4
  • b280R72b48eOm77a25YCj093DE5d9549Gc73Jg8TdD9Z0Nj4b98760
  • 051b33654C0Eg201cfW0e6NA4b9614ze8D2FN49E12Y0zY557aUCb8
  • y67Q86ffd83G0z00M0Z152f7O2ADcY313gD7a774fc5FF069zdb5b7

Bu, kullanıcılar için bir arayüz oluşturmak için çok yapılandırılabilir değil, ancak bazı amaçlar için sorun değil. Özel karakterlerin eksikliğini hesaba katmak için karakter sayısını artırın.


3
  1. İçinde bu kod bulunan bir dosya oluşturun.
  2. Yorumlarda olduğu gibi çağırın.

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

Daha kapsamlı ve güvenli bir şifre betiği oluşturdum. Bu, iki büyük harf, iki küçük harf, iki sayı ve iki özel karakterin birleşimini oluşturur. Toplam 8 karakter.

$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

Bu aslında (çok?) Yanlış. Aslında alfabedeki her karakteri sadece bir kez kullanır, böylece olası tüm değerlerin (çatlama ile ilgili) alanını ciddi şekilde daraltır.
Radoslav Bodo

0

En az bir küçük harf, bir büyük harf, bir basamak ve bir özel karakter içeren 8 uzunluğunda güçlü bir şifre oluşturur. Koddaki uzunluğu da değiştirebilirsiniz.

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

Bu işlev, parametrelerdeki kurallara göre bir şifre oluşturur

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

İşte rastgele düz şifre oluşturma yardımcısı.

Parolanın sayıları, büyük ve küçük harfleri ve en az 3 özel karakteri olmasını sağlar.

Parolanın uzunluğu 11 ile 30 arasında olacaktır.

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);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.