Arminius ha menzionato la semplicità dell'esagono, e penso che sia qualcosa su cui valga la pena espandersi.
Generatori di numeri casuali di solito lavorano su bit, quindi l'intervallo di numeri che possono generare è una potenza di due. Un intervallo di caratteri come [0-9a-zA-Z]
ha 62 caratteri, il che equivale a due volte una potenza di due (64), quindi il computer deve eseguire alcune conversioni tra gli intervalli.
Questo può essere fatto, ma è facile sbagliarlo. Il modo "standard" consiste nel prendere il numero effettivo, dividerlo per l'intervallo desiderato e prendere il resto come numero casuale. Ciò introduce però pregiudizi. Per un semplice esempio, supponi di generare numeri in [0-3]
ma invece li vuoi in [0-2]
. L'intervallo [0-3]
verrebbe mappato sull'intervallo [0-2]
in questo modo:
0 => 0 mod 3 => 0
1 => 1 mod 3 => 1
2 => 2 mod 3 => 2
3 => 3 mod 3 => 0
Nota come puoi ottenere 0
in due modi diversi: 0
e 3
entrambi vanno a 0
. L'approccio è distorto verso la generazione di 0
s, che renderà la tua password più facile da indovinare.
Il modo corretto comporta il calcolo del padding corretto per rendere uniformemente ciò che hai generato nell'intervallo, il che è complicato e potrebbe potenzialmente rendere la tua password molto più lunga a seconda di come il tuo intervallo di output è comparabile a quello del generatore di numeri casuali.
Un approccio più semplice consiste semplicemente nell'utilizzare un intervallo che è già una potenza di due in modo da poter ignorare completamente il pregiudizio. La maggior parte ha problemi.
- Base-2 (binario) produce stringhe estremamente lunghe.
- Base-4 (quaternario) non è molto meglio.
- Base-8 (ottale) è migliore ma ancora lunga.
- Base-16 (esadecimale) è un po 'lungo, ma ragionevole. Codifica anche 4 bit per carattere, il che è piuttosto conveniente quando i computer preferiscono multipli di 8.
- Base-32 codifica 5 bit per carattere, che è non conveniente quando i computer preferiscono multipli di 8.
- Base-64 codifica 6 bit per carattere, che è ancora scomodo (ma leggermente inferiore poiché almeno è un numero pari).
- Base-96 è popolare, ma non una potenza di 2 quindi ha lo stesso problema di
[0-9a-zA-Z]
.
- Base-128 e soprattutto coinvolgono simboli che non puoi facilmente digitare su una tipica tastiera querty.
Per espandere un po 'il motivo per cui base-64 è un problema, considera cosa succede quando provi a codificare un singolo byte (8 bit). Non è possibile farlo con un singolo carattere base 64 poiché questo ottiene solo 6 degli 8 bit. Ma se usi due caratteri, devi capire come riempire il tuo byte da 8 bit con un output a 12-bit senza introdurre bias o suggerendo che potrebbe esserci un byte extra.
Esadecimale, al contrario, è quasi banale codificare i byte. Basta cercare ogni byte in una tabella di 256 elementi per ottenere due caratteri e sputarli fuori. Dà password ragionevolmente brevi, non usa simboli strani, ed è semplice da implementare. È la scelta migliore per i generatori di password attenti alla sicurezza.
Forse la cosa migliore è che la maggior parte dei linguaggi di programmazione supportano l'hex out of the box. La libreria C ha printf()
, che può essere formattato come ottale, decimale o esadecimale. Allo stesso modo, C ++ ha I manipolatori IO che usano gli stessi formati. Non c'è però un supporto integrato per altre basi (nemmeno la base-64), quindi devi farlo da solo (difficile) o trovare una libreria che funzioni correttamente (violando la regola NIH (e probabilmente anche un sacco di lavoro per verificarlo)). È molto più semplice usare semplicemente ciò che è nella libreria standard, specialmente quando funziona.
È vero che hai meno sicurezza per personaggio con l'esagono che con altre codifiche, ma come Eric Lagergren ha sottolineato utilmente nei commenti, hex(random_bytes)
è esattamente sicuro quanto random_bytes
. È solo più lungo è tutto. In realtà, tutto ciò di cui hai bisogno sono 16 byte (codificati come 32 cifre esadecimali) per avere una password così strong che qualsiasi attaccante brucerà tutta l'energia nel sistema solare prima che ottengano una minuscola possibilità di indovinarlo. La maggior parte dei siti Web accetta volentieri le password di 32 caratteri, quindi non ci sono problemi a utilizzarle.