Próbuję wygenerować losowe hasło w php.
Jednak dostaję wszystkie „a”, a zwracanym typem jest tablica typów i chciałbym, aby był to ciąg znaków. Wszelkie pomysły na poprawienie kodu?
Dzięki.
function randomPassword() {
$alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
for ($i = 0; $i < 8; $i++) {
$n = rand(0, count($alphabet)-1);
$pass[$i] = $alphabet[$n];
}
return $pass;
}
/dev/random
wystarczające są odpowiedzi, ponieważ pytanie nie wymaga hasła „ bezpiecznego ” (i nie powinno być edytowane, aby je zawierało, ponieważ zmieniłoby to znaczenie pierwotnego pytania). Chociaż jestem za bezpieczeństwem, myślę, że ta dywanowa bomba nie została w pełni przemyślana. Podobnie jak przy użyciumysql_*
, odpowiedzi są nadal aktualne, ale należy je oznaczyć jako niepewne. Być może jest to coś, co SO musi uwzględnić jako dodatkowe oprogramowanie - możliwość ostrzegania przed niebezpiecznym kodem?Odpowiedzi:
Spróbuj tego (użyj
strlen
zamiastcount
, ponieważcount
na ciąg jest zawsze1
):Demo: http://codepad.org/UL8k4aYK
źródło
$pass .= $alphabet[$n]
.mt_rand
ma też lepszego)openssl_random_pseudo_bytes()
jest używana zamiastrand()
TL; DR:
random_int()
i podanerandom_str()
poniżej.random_int()
, użyj random_compat .Wyjaśnienie:
Ponieważ generujesz hasło , musisz upewnić się, że hasło, które generujesz, jest nieprzewidywalne, a jedynym sposobem zapewnienia obecności tej właściwości w implementacji jest zastosowanie kryptograficznie bezpiecznego generatora liczb pseudolosowych (CSPRNG).
Wymóg dotyczący CSPRNG można złagodzić w ogólnym przypadku losowych ciągów, ale nie w przypadku zabezpieczeń.
Prostą, bezpieczną i poprawną odpowiedzią na generowanie haseł w PHP jest użycie RandomLib i nie wymyślanie koła na nowo. Ta biblioteka została zbadana przez ekspertów branży bezpieczeństwa, a także przeze mnie.
Dla programistów, którzy wolą wymyślić własne rozwiązanie, PHP 7.0.0 zapewni
random_int()
do tego celu. Jeśli nadal korzystasz z PHP 5.x, napisaliśmy polifill dla PHP 5random_int()
, abyś mógł używać nowego API przed wydaniem PHP 7. Korzystanie z naszegorandom_int()
wypełniacza jest prawdopodobnie bezpieczniejsze niż napisanie własnej implementacji.Mając pod ręką bezpieczny generator losowych liczb całkowitych, wygenerowanie bezpiecznego ciągu losowego jest łatwiejsze niż ciasto:
źródło
mcrypt_*
funkcji. Widzę w wątku , że rozwidliłeś bibliotekę, ponieważ nie jesteś w stanie uzyskać @ircmaxell, ale twój widelec mówi „kompilacja nie powiodła się” na Travis. Czy chcesz zaktualizować tę odpowiedź (która wciąż pojawia się dość wysoko w Google)?Wiem, że próbujesz wygenerować hasło w określony sposób, ale możesz również przyjrzeć się tej metodzie ...
Jest pobierany ze strony php.net i tworzy ciąg, który jest dwa razy dłuższy niż liczba podana w funkcji openssl_random_pseudo_bytes. Tak więc powyższe utworzy hasło o długości 4 znaków.
W skrócie...
Utworzy hasło o długości 8 znaków.
Pamiętaj jednak, że hasło zawiera tylko cyfry 0–9 i małe litery af!
źródło
openssl_random_pseudo_bytes()
jest potężnym generatorem losowości bajtów binarnych i nie wymaga dalszego tasowania. Zaryzykuję również wskazanie, że zakładanie, że stosowanie wielu metod szyfrowania sprawi, że wszystko stanie się bardziej losowe, w niektórych przypadkach może być wręcz przeciwnie z powodu kumulacji kolizji mieszających.Mały kod z 2 liniami.
demo: http://codepad.org/5rHMHwnH
źródło
substr(str_shuffle(str_repeat($chars,$length)),0,$length);
Jeśli korzystasz z PHP7, możesz użyć
random_int()
funkcji:źródło
mt_rand
do generowania hasła.mt_rand
, więc nadal nie nadaje się do celów bezpieczeństwa.$chars
W jednej linii:
źródło
substr(str_shuffle(str_repeat($chars,$length)),0,$length);
Przywrócono EntropięTwój najlepszy zakład to biblioteka RandomLib firmy ircmaxell .
Przykład użycia:
Tworzy ciągi, które są silniej losowe niż normalne funkcje losowości, takie jak
shuffle()
irand()
(to jest to, czego zazwyczaj potrzebujesz dla poufnych informacji, takich jak hasła, sole i klucze).źródło
rand()
lubmt_rand()
.random_bytes
), ale nie powoduje to, żerand
odpowiedzi są nieprawidłowe.rand
nie jest dobrym wyborem dla hasełrand()
nieprawidłowe. Wszystkie są nieprawidłowe same w sobie!Chcesz
strlen($alphabet)
, a niecount
stałejalphabet
(odpowiednik'alphabet'
).Nie
rand
jest to jednak odpowiednia funkcja losowa do tego celu. Jego wynik można łatwo przewidzieć, ponieważ jest domyślnie zaszczepiony bieżącym czasem. Ponadtorand
nie jest kryptograficznie bezpieczny; dlatego stosunkowo łatwo jest ustalić jego stan wewnętrzny na podstawie wyjścia.Zamiast tego czytaj od,
/dev/urandom
aby uzyskać kryptograficznie losowe dane.źródło
Zamierzam opublikować odpowiedź, ponieważ niektóre z istniejących odpowiedzi są bliskie, ale mają jedną z:
Ta odpowiedź obejdzie
count/strlen
problem, ponieważ bezpieczeństwo wygenerowanego hasła, przynajmniej IMHO, wykracza poza to, jak się tam dostaniesz. Zakładam też, że PHP> 5.3.0.Podzielmy problem na części składowe, które są:
W pierwszej części PHP> 5.3.0 udostępnia tę funkcję
openssl_random_pseudo_bytes
. Zauważ, że chociaż większość systemów używa silnego algorytmu kryptograficznego, musisz to sprawdzić, abyśmy użyli opakowania:W drugiej części wykorzystamy,
base64_encode
ponieważ zajmuje ona ciąg bajtów i tworzy serię znaków, których alfabet jest bardzo zbliżony do alfabetu podanego w pierwotnym pytaniu. Jeśli nie przeszkadza nam to+
,/
a=
znaki pojawiają się w końcowym ciągu znaków i chcemy uzyskać wynik o$n
długości co najmniej znaków, możemy po prostu użyć:3/4
Czynnikiem jest to spowodowane faktem, że base64 kodującego wyników w ciąg, który ma długość co najmniej jedną trzecią większy niż ciąg bajtów. Wynik będzie dokładny, ponieważ w przeciwnym$n
razie będzie wielokrotnością 4 i maksymalnie 3 znaków. Ponieważ dodatkowe znaki to głównie znak dopełniający=
, jeśli z jakiegoś powodu mieliśmy ograniczenie, że hasło ma dokładną długość, możemy je skrócić do żądanej długości. Jest tak szczególnie dlatego, że dla danego$n
hasła wszystkie hasła kończą się taką samą liczbą, aby osoba atakująca, która miała dostęp do hasła wynikowego, mogła zgadnąć maksymalnie 2 znaki.Aby uzyskać dodatkowy kredyt, jeśli chcielibyśmy spełnić dokładną specyfikację jak w pytaniu PO, musielibyśmy wykonać trochę więcej pracy. Mam zamiar zrezygnować z podstawowego podejścia do konwersji i przejść do szybkiego i brudnego. Oba muszą generować więcej losowości, niż i tak zostanie użyte w wyniku z powodu alfabetu o długości 62 pozycji.
W przypadku dodatkowych znaków w wyniku możemy po prostu odrzucić je z powstałego ciągu. Jeśli zaczniemy od 8 bajtów w naszym łańcuchu bajtów, wówczas około 25% znaków base64 będzie tymi „niepożądanymi” znakami, więc po prostu odrzucenie tych znaków spowoduje, że łańcuch nie będzie krótszy niż oczekiwany PO. Następnie możemy po prostu go przyciąć, aby uzyskać dokładną długość:
W przypadku generowania dłuższych haseł znak wypełniający
=
stanowi coraz mniejszą część wyniku pośredniego, dzięki czemu można zastosować bardziej uproszczone podejście, jeśli problem dotyczy wyczerpania puli entropii używanej przez PRNG.źródło
openssl_random_pseudo_bytes
może to dać słaby wynik. Nie zdawałem sobie sprawy, że tak jest.base_convert(uniqid('pass', true), 10, 36);
na przykład.
e0m6ngefmj4
EDYTOWAĆ
Jak wspomniałem w komentarzach, długość oznacza, że ataki z użyciem siły brutalnej działałyby przeciwko niemu lepiej niż ataki na czas, więc nie ma sensu martwić się o „jak bezpieczny był losowy generator”. Bezpieczeństwo, szczególnie w tym przypadku użycia, musi uzupełniać użyteczność, więc powyższe rozwiązanie jest w rzeczywistości wystarczające dla wymaganego problemu.
Jednak na wypadek, gdybyś natknął się na tę odpowiedź podczas wyszukiwania bezpiecznego generatora ciągów losowych (jak zakładam, niektórzy ludzie oparli się na odpowiedziach), na przykład w celu generowania tokenów, oto jak mógłby wyglądać generator takich kodów:
źródło
Kolejny (tylko Linux)
źródło
fread()
buforuje domyślnie 8192 bajtów, więc zawsze będziesz czytać tyle/dev/urandom
z danego kodu. To również nie będzie działać w systemie Windows. Jednak pochwały za używanie CSPRNG.Być trochę mądrzejszym:
sprawdź tutaj .
źródło
Użyj tego prostego kodu do wygenerowania med-strong hasła o długości 12
źródło
Spróbuj tego z wielkimi literami, małymi literami, cyframi i znakami specjalnymi
Przykładowe dane wyjściowe:
, IZCQ_IV \ 7
@wlqsfhT (d
1! 8 + 1 \ 4 @ uD
źródło
rand
funkcja nie jest faktycznie kryptograficznego więc może to być całkiem ryzyko wygenerować hasło używając goSzybki. Prosty, czysty i spójny format, jeśli tego chcesz
źródło
Jest to oparte na innej odpowiedzi na tej stronie, https://stackoverflow.com/a/21498316/525649
Ta odpowiedź generuje tylko znaki HEX,
0-9,a-f
. Aby uzyskać coś, co nie wygląda jak hex, spróbuj tego:base64_encode
zwraca szerszy zakres znaków alfanumerycznychrtrim
usuwa=
czasem na końcuPrzykłady:
32eFVfGDg891Be5e7293e54z1D23110M3ZU3FMjb30Z9a740Ej0jz4
b280R72b48eOm77a25YCj093DE5d9549Gc73Jg8TdD9Z0Nj4b98760
051b33654C0Eg201cfW0e6NA4b9614ze8D2FN49E12Y0zY557aUCb8
y67Q86ffd83G0z00M0Z152f7O2ADcY313gD7a774fc5FF069zdb5b7
Nie jest to zbyt konfigurowalne do tworzenia interfejsu dla użytkowników, ale do niektórych celów jest to w porządku. Zwiększ liczbę znaków, aby uwzględnić brak znaków specjalnych.
źródło
Nazwij to jak w komentarzach.
źródło
Stworzyłem bardziej kompleksowy i bezpieczny skrypt hasła. Spowoduje to utworzenie kombinacji dwóch wielkich liter, dwóch małych liter, dwóch cyfr i dwóch znaków specjalnych. Łącznie 8 znaków.
źródło
źródło
Generuje silne hasło o długości 8 zawierające co najmniej jedną małą literę, jedną wielką literę, jedną cyfrę i jeden znak specjalny. Możesz także zmienić długość w kodzie.
źródło
Ta funkcja wygeneruje hasło na podstawie reguł w parametrach
źródło
Oto mój przypadkowy pomocnik w generowaniu zwykłego hasła.
Zapewnia, że hasło ma cyfry, wielkie i małe litery, a także co najmniej 3 znaki specjalne.
Długość hasła będzie wynosić od 11 do 30.
źródło