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.