L'entropia in un identificatore di sessione è l'entropia dell'origine del numero sottostante; un PRNG potrebbe produrre buone parole casuali di 32 bit, ognuna delle quali ha 32 bit di entropia (tuttavia, come sottolineato da @forrest, l'entropia non "trasporta" - crescerà fino a raggiungere la dimensione dello stato interno del PRNG, e teoricamente quello stato potrebbe essere retro-calcolato con un output sufficiente Da allora in poi, l'output PRNG è prevedibile, con un'entropia pari a 0. Un generatore "veramente casuale" ha uno stato interno di dimensioni infinite).
Ciò significa che ogni bit è più o meno completamente imprevedibile (il "più o meno" deriva dal fatto che il PRNG è un generatore di numeri casuali (P) seudo ).
Quando questo numero a 32 bit è codificato in un identificatore, solitamente mediante codifica esadecimale, diventa qualcosa come 1A9F72EF
. Ora questi sono byte , quindi 64 bit , ma contengono ancora la stessa entropia di prima, che era di 32 bit.
Se avessimo usato la codifica base64, il nostro identificatore avrebbe avuto 6 bit di entropia per ciascun carattere, cioè 8 bit; quindi l'entropia sarebbe 3/4 della lunghezza in bit dell'identificatore (o l'identificatore sarebbe 8 / 6ths della lunghezza della sua rappresentazione binaria).
Ecco da dove proviene "1/2" di OWASP.
Ora, l'entropia di una sorgente non può essere determinata osservando una singola istanza; di solito devi sapere con certezza come funziona la fonte. Una fonte casuale è per definizione pura entropia. Una fonte costante (sempre restituisce 42) ha un'entropia di zero anche quando "42" è rappresentato da sei o otto bit.
Usando un'approssimazione molto approssimativa e non affidabile, l'entropia è il doppio del numero di bit che varia in media da una rappresentazione all'altra , a condizione che le modifiche siano casuali e non ripetitive. Una sequenza di [00FF, FF00, 00FF, FF00 ...] cambierebbe tutti i suoi bit, ma nella sequenza ci sono solo due simboli, quindi un bit one è sufficiente per descriverlo completamente; lo stato interno del generatore è un po 'largo.
Il grosso problema è determinare se una fonte è "veramente" (pseudo-) casuale .
Se puoi fidarti di SecureRandom
(probabilmente puoi!), allora sì, BigInteger(130, new SecureRandom())
ti darà un numero con 130 bit di entropia. Puoi codificarlo come sequenza esadecimale a 260 bit o sequenza Base64 a 176 bit.
Assicurati solo che il pool di entropia che alimenta SecureRandom
venga aggiornato abbastanza frequentemente con una certa casualità, altrimenti il tuo identificatore potrebbe diventare prevedibile. Un caso (in) famoso è Mersenne Twister , dove avere 624 valori sequenziali dal generatore consente di ricostituire i 19967 bit del suo stato interno tramite algebra lineare, e quindi prevedere con certezza tutti i suoi valori futuri.