Generowanie losowego hasła; dlaczego to nie jest przenośne?


21

Chcę wygenerować losowe hasło i robię to tak:

</dev/urandom tr -dc [:print:] | head -c 64

Na moim laptopie, na którym działa Ubuntu, produkuje tylko zgodne z przeznaczeniem znaki do wydruku. Ale kiedy ssh na serwer mojej szkoły, na którym działa Red Hat Enterprise Linux, i tam go uruchamiam, dostaję dane wyjściowe 3!ri�b�GrӴ��1�H�<�oM����&�nMC[�Pb�|L%MP�����9��fL2q���IFmsd|l�K, które w ogóle się nie sprawdzą. Co może pójść nie tak?

Odpowiedzi:


34

To twój problem z lokalizacją i tr .

Obecnie GNU tr w pełni obsługuje tylko znaki jednobajtowe. Tak więc w lokalizacjach korzystających z kodowania wielobajtowego dane wyjściowe mogą być dziwne:

$ </dev/urandom LC_ALL=vi_VN.tcvn tr -dc '[:print:]' | head -c 64
`�pv���Z����c�ox"�O���%�YR��F�>��췔��ovȪ������^,<H ���>

Powłoka będzie poprawnie drukować znaki wielobajtowe, ale GNU trusunie bajty, które jej zdaniem nie można wydrukować.

Jeśli chcesz, aby był stabilny, musisz ustawić ustawienia regionalne:

$ </dev/urandom LC_ALL=C tr -dc '[:print:]' | head -c 64
RSmuiFH+537z+iY4ySz`{Pv6mJg::RB;/-2^{QnKkImpGuMSq92D(6N8QF?Y9Co@

14
+1, ponieważ to uświadomiło mi (używanie powłok w systemie Unix / Linux tylko przez około 30 lat), że przekierowanie stdin / stdout / stderr nie musi być pozycjonowane po poleceniu, którego dotyczy.
— Anthon

Tylko komentarz, jeśli ustawione są dziwne ustawienia narodowe, czy powłoka nadal nie będzie mogła poprawnie drukować znaków, nawet jeśli nie są one ascii? Przynajmniej kompetentna powłoka (oczywiście bez Xterma)?
— orion

2
@orion: powłoka poprawnie wydrukuje znaki. W tym przypadku jest to problem z tr. Usunął bajty, które według niego nie nadają się do wydruku, co sprawia, że ​​wynik jest dziwny.
— cuonglm

@orion Równomiernie losowy strumień bajtów nie będzie na ogół równomiernie losowym strumieniem dobrze uformowanych kodowań znaków UTF-8 .
— zwolnienie

Ponadto, chyba że masz spacje w swoim haśle, powinieneś użyć :graph:zamiast :print::</dev/urandom LC_ALL=C tr -dc '[:graph:]' | head -c 64
— edan

11

Zastanów się zamiast tego

$ dd if=/dev/urandom bs=48 count=1 status=none | base64
imW/X60Sk9TQzl+mdS5PL7sfMy9k/qFBWWkzZjbYJttREsYpzIguWr/uRIhyisR7

Ma to dwie zalety:

  • Z losowego urządzenia odczytujesz tylko 48 bajtów, a nie ~ 8 KB; jeśli inne procesy na tym samym hoście wymagają liczb losowych, wyczerpanie 8 KB na raz może być poważnym problemem. (Tak, prawdopodobnie nikt nie powinien używać blokującego urządzenia losowego, ale ludzie tak robią ).

  • Produkcja nie base64zawiera prawie żadnych znaków o specjalnych znaczeniach. (Dla wcale, hals | tr +/ -_na końcu, i (jak w przykładzie), upewnij się, że liczba bajtów wejścia do base64jest wielokrotnością 3)

Hasło wygenerowane w ten sposób ma dokładnie 384 bity entropii, co jest nieco mniej niż to, co robiłeś (log 2 96 64 ≈ 421,4), ale więcej niż wystarcza do większości celów (256 bitów entropii bezpiecznie „zgaduje, kiedy Słońce wypala ”terytorium z wyjątkiem kluczy RSA, AFAIK).


3

Inne osoby już zwróciły uwagę, że lokalizacja określa, co [:print:]oznacza. Jednak nie wszystkie znaki drukowalne są odpowiednie dla haseł (nawet w ascii). Naprawdę nie chcesz spacji, tabulatorów i # $% ^? w swoim haśle - nie tylko jest to trudne do zapamiętania, ale także potencjalnie niebezpieczne dla bazowego systemu uwierzytelniania, może być niemożliwe wprowadzenie pola wprowadzania danych i tak dalej. W takim przypadku powinieneś po prostu ręcznie wybrać „rozsądne” znaki:

LC_ALL=C </dev/urandom tr -dc '[:alnum:]_' | head -c 64

lub po prostu

</dev/urandom tr -dc 'A-Za-z0-9_' | head -c 64

Lub jeszcze lepiej, użyj base64zgodnie z sugestią w innych odpowiedziach.


Hasło, o którym mowa, nigdy nie zostanie wprowadzone przez ludzi (gdyby to było, użyłbym zamiast tego Diceware) i jestem całkiem pewien, że podstawowy system bez problemu poradzi sobie ze znakami specjalnymi. W każdym razie dzięki.
— Taymon

4
To, co mówisz, jest całkowicie błędne. Zmuszenie użytkowników do używania tylko liter ascii, cyfr i podkreślenia znacznie zmniejsza rozmiar alfabetu, znacznie ułatwiając łamanie haseł atakującym. System uwierzytelniania, który nie jest w stanie obsłużyć ?lub ^jest po prostu zbyt zły, aby traktować go poważnie.
— Bakuriu

2
Jeśli twój system uwierzytelniania lub pola wprowadzania dławią się zwykłymi symbolami ASCII ... to robisz coś złego i nie możesz ufać moim prywatnym informacjom. Nie ma absolutnie żadnego powodu, aby nie akceptować wszelkiego rodzaju znaków (w tym spacji) w hasłach.
— nzifnab

2
Wydaje się, że tak nie jest, ale jeśli chodzi o wkład człowieka, o wiele łatwiej jest zapamiętać długie hasło alfanumeryczne, które ma unikalne znaczenie dla właściciela niż krótsza zbieranina symboli. Istnieje również problem z wprowadzaniem tych znaków na różnych klawiaturach (nie wszyscy mają ^ na pierwszym poziomie i większość ludzi nawet nie wie, gdzie jest i co to jest backtick), pola wprowadzania prawie na pewno nie obsługują znaku tabulacji i zaskakująca liczba formularzy internetowych wciąż jest podatna na błędy sprawdzania poprawności, wstrzykiwanie kodu SQL, a nawet niepewność co do wielkości liter.
— orion

1
Tylko uwaga: w locale C [:print:]klasa ma nie zawierać karty. To tylko [:alnum:]+ [:punct:]+ spacja (pojedyncza spacja, nie [:space:] ).
— jimmij

2

Co powiesz na

tr -dc [:print:] < /dev/urandom | head -c 64 | strings

ciągi powinny wypisywać dane wyjściowe z urandom w formacie do wydruku


To daje-bash: /dev/urandom: Permission denied
— Anthon

przepraszam, zapomniałem wiodącego kota
— Blindstealer

2

Nie wiem, czy jest jakiś powód, dla którego /dev/randomgenerujesz hasło, ale zalecałbym używanie pwgen w celu złagodzenia bólu.

$ pwgen -s 10 1

Gdzie 10 to długość hasła.

http://man.cx/pwgen


1
#Chars allowed in password (I don't like l,o,O, etc):
P="0123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz"

#Or such:
#P="a-zA-Z0-9"

head -c 8 < /dev/urandom | tr '\000-\377' "$P$P$P$P$P"
echo

Ta metoda IMHO jest mądrzejsza, gdy pobiera dane z / dev / urandom Łańcuch wklejony jako $ P $ P $ P ... musi mieć co najmniej 256 znaków.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.