comando Unix per generare stringhe casuali crittograficamente sicure

8

Il seguente comando Unix è crittograficamente sicuro per generare in modo casuale 20 caratteri (solo a-zA-Z0-9)?

dd if=/dev/urandom bs=256 count=1 2> /dev/null | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c20

C'è un modo migliore o più sicuro per farlo in Unix?

    
posta Justin 18.04.2018 - 01:09
fonte

1 risposta

15

No, non è completamente sicuro. Diamo un'occhiata a ciascuno dei comandi:

dd if=/dev/urandom bs=256 count=1 2> /dev/null

Questo leggerà un singolo blocco da 256 byte da /dev/urandom , una fonte casuale protetta da crittografia. Il problema inizia qui ed è correlato a questo limite di 256 byte. In effetti, non è nemmeno necessario utilizzare dd qui. Il prossimo comando è perfettamente in grado di leggere da solo un dispositivo a blocchi.

LC_ALL=C tr -dc 'A-Za-z0-9'

Questo comando rimuove tutti i caratteri che non sono alfanumerici. Il LC_ALL=C limita il set di caratteri al semplice ASCII, dove [:alnum:] corrisponderà a 62 caratteri. Simboli e caratteri non stampabili saranno rimossi. Il problema ora è che a questo comando sono dati solo 256 byte, quindi cosa succede se troppo pochi di quei byte sono alfanumerici? Il comando tr prenderà felicemente 256 byte di input e sputerà solo un paio di byte di output se solo un paio di byte corrisponde al filtro.

head -c20

Questo comando tronca semplicemente l'output a 20 byte. L'output effettivo varierà tra 0 e 20 caratteri. * Statisticamente, è molto probabile che emetta ogni volta 20 caratteri interi.

Un modo migliore per ottenere caratteri alfanumerici casuali può essere fatto con meno comandi. Questo avrà tr letto quanti più dati da /dev/urandom di cui ha bisogno, sputando continuamente ASCII alfanumerico al comando successivo. Non appena head ha i 20 byte richiesti, chiuderà la pipe, causando tr per interrompere la lettura di dati casuali ed uscire. Questo è quello che dovresti usare:

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

Ciò garantirà 20 caratteri casuali, con una forza equivalente di log 2 (62 20 ) ≈ 119.1 bit.

* Il rischio è in gran parte teorico. Ogni byte ha una probabilità (256 - 62) / 256 (circa il 76%) di non di essere alfanumerico. La probabilità che almeno 256 - 20 byte non siano alfanumerici è molto bassa, ma diversa da zero: (194/256) 236 ≈ 3.8 × 10 -28 .

    
risposta data 18.04.2018 - 04:47
fonte

Leggi altre domande sui tag