<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>dd &amp;mdash; Cyberdyne Systems</title>
    <link>https://noblogo.org/aytin/tag:dd</link>
    <description>&#34;Fare o non fare. Non c&#39;è provare!&#34;</description>
    <pubDate>Thu, 30 Apr 2026 07:18:46 +0000</pubDate>
    <item>
      <title>Come generare una password o un keyfile sicuri (Trilogia Della Password - 1 di 3)</title>
      <link>https://noblogo.org/aytin/come-generare-una-password-o-un-keyfile-sicuri-trilogia-della-password-1-di</link>
      <description>&lt;![CDATA[password&#xA;&#xA;La generazione di una password o di un keyfile si basa sulla casualità ossia sulla capacità del sistema di generare sequenze di simboli non prevedibili.&#xA;In questo contesto bisogna avere chiari 3 concetti legati fra loro: casualità, sorgente d&#39;entropia, entropia della password.&#xA;!--more--&#xA;&#xA;Definizioni varie&#xA;Entropia del kernel (CSPRNG)&#xA;Come generare password e keyfile&#xA;   Analisi&#xA;   Valutazione&#xA;   Conclusione&#xA;Bonus - Modalità paranoia&#xA;   Generazione password&#xA;   Generazione keyfile&#xA;   GPG Random&#xA;Riepilogo finale&#xA;   2) Keyfile binario&#xA;   3) Password complessa con caratteri stampabili&#xA;   5) Keyfile binario con openssl&#xA;&#xA;Definizioni varie&#xA;Casualità&#xA;In generale, posso parlare di casualità quando non riesco ad individuare un pattern o un&#39;organizzazione deterministica in una sequenza di dati.&#xA;&#xA;Da un punto di vista crittografico, una sequenza è considerata &#34;casuale&#34; se non esiste un algoritmo che possa prevedere il bit successivo con una probabilità superiore al 50% (puro caso).&#xA;&#xA;Sorgente d&#39;entropia&#xA;La casualità è resa possibile dalla sorgente d&#39;entropia che è il dispositivo o il processo fisico che genera il rumore grezzo per produrre dati casuali. È l&#39;origine dell&#39;incertezza e il suo grado di &#34;purezza&#34; è fondamentale per la produzione della casualità.&#xA;&#xA;Le sorgenti di entropia possono essere fisiche (TRNG) o software (PRNG). In quest&#39;ultimo caso si parla di pseudo-casualità perché si tratta di algoritmi che espandono un seed (un seme) casuale in una sequenza anche arbitrariamente lunga che sembra casuale.&#xA;&#xA;Bit di entropia di una sequenza&#xA;O entropia della sequenza, è la misura numerica di quanto sia imprevedibile la sequenza casuale di dati.&#xA;&#xA;Quindi:&#xA;&#xA;la sorgente di entropia è il nostro generatore di incertezza;&#xA;la casualità, la cui qualità dipende totalmente dalla prima, è il processo che produce la sequenza di dati;&#xA;l&#39;entropia, in termini di bit, che è funzione della lunghezza della sequenza e del set di simboli a disposizione, è la misura di quanto la sequenza sia crittograficamente non prevedibile.&#xA;&#xA;Entropia del kernel (CSPRNG)&#xA;Su una qualunque linuxbox il protagonista per la generazione dell&#39;entropia necessaria è ovviamente sua maestà il kernel, che è fatto per essere anche un CSPRNG, impronunciabile acronimo che sta per Cryptographically Secure Pseudo-Random Number Generator.&#xA;&#xA;Il kernel infatti, già dall&#39;avvio, raccoglie entropia (entropy harvesting), rumore casuale direttamente dall&#39;hardware (interrupt del disco, tastiera, mouse, istruzioni CPU come RDRAND). Questi dati grezzi vengono mescolati in un serbatoio (l&#39;entropy pool) da cui l&#39;algoritmo (ChaCha20) pesca per espandere questi dati in un flusso infinito di dati pseudo casuali.&#xA;&#xA;Per avere una misura di quanta casualità abbia il sistema possiamo ricorrere al seguente costrutto:&#xA;cat /proc/sys/kernel/random/entropyavail&#xA;un valore da 256 in poi ci dice abbiamo entropia sufficiente per generare chiavi e quant&#39;altro.&#xA;&#xA;Finita la parte di teoria, vediamo in quanti modi possiamo generare una password bella robusta o un keyfile.&#xA;Come generare password e keyfile&#xA;Per generare sequenze di dati casuali possiamo seguire 2 vie:&#xA;&#xA;attingere direttamente alla sorgente di entropia fornita dal kernel;&#xA;usare la sorgente per prelevare un seme e generare la sequenza casuale via software che è la via di openssl e di pwgen.&#xA;&#xA;Modalità&#xA;&#xA;dd if=/dev/urandom of=mykey.bin bs=4096 count=1 iflag=fullblock status=none&#xA;head -c 4K /dev/urandom   mykey.bin&#xA;tr -dc &#39;[:graph:]&#39;  /dev/urandom | head -c 4096  mykey.txt&#xA;pwgen -s 4095 1   mykey.txt&#xA;openssl rand -out mykey.bin 4096&#xA;&#xA;Analisi&#xA;Come si comportano questi procedimenti? Proviamo ad analizzarli.&#xA;&#xA;Casualità&#xA;Una prima distinzione va fatta sulla modalità di creazione della casualità.&#xA;&#xA;I primi 3 metodi fanno riferimento direttamente alla sorgente senza introdurre altre stratificazioni software. Sul piano teorico, rappresentano il punto più vicino alla casualità fisica che si possa avere su un computer.&#xA;&#xA;Openssl e pwgen no, sono due consumatori per /dev/urandom. &#xA;Devono prima pescare un seme da /dev/urandom.&#xA;Una volta ottenuto il seme, usano i propri algoritmi (quelli di openssl sono solitamente basati su AES-CTR o SHA2) per generare una sequenza infinita di numeri casuali.&#xA;Pwgen fa una cosa simile ma è stato progettato di base per costruire password pronunciabili (minore entropia intrinseca).&#xA;&#xA;Velocità&#xA;Openssl, fra tutti, è il più veloce, soprattutto se si ha l&#39;esigenza di produrre casualità per volumi di decine di giga o di tera.&#xA;Ciò è dovuto al fatto che openssl effettua pochissime syscall per prelevare il seme per poi spremere solo la cpu che, supportando quasi certamente le istruzioni hardware AES-NI, rende il processo poco impegnativo per la cpu stessa e brutalmene efficiente.&#xA;Agire solo sul kernel, pur conservando la purezza della casualità, causa un rallentamento notevole dovuto al grandissimo numero di syscall necessarie e dalla corrispondente attivazione degli algoritmi di cifratura. Inoltre, mentre dd può contare su un buffer relativamente più capiente, cat, tr, head o qualuque altro oggetto che &#34;beva&#34; direttamente da /dev/urandom, hanno dei buffer molto più piccoli a disposizione, 1MB vs 8-16KB, il cui rapporto funge da moltiplicatore sul numero di operazioni necessarie.&#xA;&#xA;Sicurezza&#xA;Tutti i procedimenti indicati, sono estremamente sicuri, anzi, crittograficamente sicuri. Fermo restando che vale sempre l&#39;osservazione fatta sopra sulla metrica dell&#39;entropia di una sequenza casuale: è funzione del set di caratteri e della lunghezza della sequenza. Conti alla mano, con un alfabeto di una settantina di caratteri, una sequenza di almeno 20 caratteri possiederà un&#39;entropia di circa 120 bit che la rendono impenetrabile per gli attuali sistemi di calcolo.&#xA;&#xA;Usare direttamente la sorgente d&#39;entropia, è sicuramente più vantaggioso perché ci fidiamo del kernel.&#xA;Inoltre è più isolato perché lavora a livello del kernel dove i processi utente, anche quelli malevoli, non possono accedere alle sue zone di memoria.&#xA;&#xA;Openssl, pwgen e tutti quelli che sono generatori secondari, possono incorrere in quella che si diefinisce duplicazione della casualità.&#xA;Se l&#39;applicazione non è scritta bene, c&#39;è il rischio che il processo, forkandosi, possa &#34;duplicare&#34; la casualità. In sostanza, i processi padre e figlio finiranno per produrre la stessa sequenza di simboli casuali. Una catastrofe.&#xA;Vecchie versioni di openssl, ante 1.1.1 per es., hanno sofferto di questa anomalia.&#xA;Valutazione&#xA;I metodi 1,2,5 producono un keyfile di dati binari, quindi con un entropia enorme quasi vicina all&#39;ottimo teorico.&#xA;Come detto, openssl è mostruosamente più veloce.&#xA;&#xA;Volendo essere purista, per un keyfile i metodi 1 e 2 (praticamente equivalenti) sono da preferire.&#xA;Per produrre tera di dati casuali (storage, test di rete) sicuramente openssl. Se il volume non dovesse essere esagerato e siamo paranoici, anche il metodo 1 può andare bene.&#xA;&#xA;Per la produzione di una password complessa con simboli stampabili (non necessariamente pronunciabile altrimenti l&#39;entropia sarebbe ancora più bassa) il metodo 3 è da preferire da un punto di vista matematico.&#xA;&#xA;Mettendo da parte openssl che fa comunque un ottimo lavoro (universalmente riconosciuto con tanto di certificazioni FIPS-2), voglio spendere due parole su pwgen.&#xA;pwgen, con il flag -s, crea delle sequenze completamente randomiche su un alfabeto di 62 caratteri.&#xA;Se la lunghezza della sequenza è   = 20, e quindi con un&#39;entropia teorica di ~115-120, avremo delle password abbastanza inviolabili dagli attuali sistemi di calcolo.&#xA;Usare il flag -y potrebbe sembrare una buona idea perché si forza ad estendere il set di caratteri.&#xA;Sicuramente da una parte aumenta l&#39;entropia della sequenza generata, visto che l&#39;alfabeto è molto più vasto. Dall&#39;altra però la forzatura va a compromettere l&#39;uniformità della distribuzione casuale dei simboli.&#xA;Conclusione&#xA;&#xA;password/keyfile stampabile: tr -dc &#39;[:graph:]&#39;  /dev/urandom | head -c [n]  mykey.txt&#xA;password/keyfile binario: head -c [n] /dev/urandom   mykey.bin (equivalentemente dd if=/dev/urandom of=mykey.bin bs=4096 count=1 iflag=fullblock status=none)&#xA;cancellazione disco: openssl rand [dimdisco] | dd of=/dev/sdX bs=1M status=progress&#xA;&#xA;Bonus - Modalità paranoia&#xA;Generazione password&#xA;Se non ci fidassimo della sorgente di casualità, possiamo aggiungere alla sorgente di entropia un nostro segreto personale e &#34;mescolarli&#34; attraverso una funzione sha256 o sha512 rendendo il tutto ancora crittograficamente sicuro.&#xA;&#xA;(head -c 4K /dev/urandom ; read -s -p &#34;Per aumentare l&#39;entropia inserisci una frase segreta o premi tasti a caso: &#34; secret) | sha512sum | cut -d&#39; &#39; -f1   mykey.txt.&#xA;&#xA;È certamente una password molto robusta per violare la quale occorrerebbe compromettere la sorgente d&#39;entropia e indovinare il segreto personale (N.B. stiamo facendo l&#39;ipotesi che si provi a rompere il meccanismo di generazione della chiave non che si provi l&#39;enumerazione attraverso un attacco brute-force).&#xA;&#xA;Generazione keyfile&#xA;Per produrre un keyfile di 4096 bytes con la stessa premessa, faremo uso di openssl.&#xA;&#xA;si genera esplicitamente un seme dalla sorgente di entropia del kernel&#xA;come prima, con sha2 si mescola  il seme con un nostro segreto&#xA;si dà in pasto ad openssl.&#xA;&#xA;Creiamo un seme unico mescolando /dev/urandom e il mio input con sha512&#xA;Usiamo quel seme per generare 4KB di dati casuali &#34;espansi&#34;&#xA;(head -c 256 /dev/urandom; read -s -p &#34;Per aumentare l&#39;entropia inserisci una frase segreta o premi tasti a caso: &#34; secret; echo &#34;$secret&#34;) | sha512sum | cut -d &#34; &#34; -f1 | openssl enc -aes-256-ctr -pbkdf2 -pass stdin -nosalt -in /dev/zero | head -c 4096   mykey.bin&#xA;L&#39;errore che compare alla fine è un falso negativo, dovuto al fatto che openssl sta ancora provando a scrivere dati e head li tronca all&#39;improvviso. &#xA;&#xA;Giusto due righe di spiegazione:&#xA;&#xA;head -c 256 /dev/urandom: preleva un po&#39; di dati casuali &#34;puri&#34;&#xA;read -sp secret: si inserisce una password, una frase o tasti schiacciati a caso per aumentare l&#39;entropia&#xA;sha512sum | cut -d &#34; &#34; -f1: si mescola tutto e si preleva solo l&#39;esadecimale di 64 bytes&#xA;openssl enc -aes-256-ctr -pbkdf2 -pass stdin -nosalt -in /dev/zero: openssl, che riceve il seme sullo stdin, fa la sua magia producendo un fiume di dati casuali&#xA;head -c 4096: tronca il &#34;fiume&#34; alla lunghezza voluta per il nostro keyfile&#xA;&#xA;Quindi:&#xA;&#xA;Contro i bug del kernel: se la nostra sorgente d&#39;entropia fosse compromessa e diventasse deterministica, occorrerebbe comunque conoscere il nostro segreto&#xA;Contro il keylogging: anche se il nostro segreto potesse essere svelato, la sorgente d&#39;entropia garantirebbe comunque l&#39;inviolabilità della nostra password&#xA;&#xA;GPG Random&#xA;Quando si parla di paranoia, un altro ottimo candidato per produrre password e keyfile è certamente GPG.&#xA;GPG non si llimita a copiare dati da /dev/urandom ma utilizza una propria libreria crittografica chiamata Libgcrypt, che implementa un generatore di numeri pseudocasuali, crittograficamente sicuro, molto sofisticato.&#xA;&#xA;A differenza di ciò che abbiamo visto finora, GPG permette di impostare un livello di qualità per la casualità da produrre.&#xA;&#xA;livello 0 (Debole): per scopi didatti, usato raramente.&#xA;livello 1 (Avanzato): adatto per chiavi di sessione e cifratura standard. Corrisponde ad una casualità di alta qualità&#xA;livello 2 (Forte): utilizzato per le chiavi a lungo termine (le chiavi private di GPG). È un livello estremamente conservativo. Se GPG valuta di non avere entropia sufficientemente fresca, si mette in attesa.&#xA;&#xA;GPG non si fida ciecamente del kernel e così Libgcrypt crea un proprio pool di entropia in user space.&#xA;&#xA;Libgcrypt pesca al solito un seme da /dev/urandom&#xA;il seme viene rimescolato con sha2 o aes&#xA;per evitare che i dati casuali finiscano sullo swap, libgcrypt usa pagine di memoria protetta (mlock)&#xA;&#xA;Impostando il livello 2, libgcrypt può decidere di scartare molti più dati se ritiene che il pool di entropia non sia abbastanza &#34;fresco&#34;. Inoltre, in virtù della sua diffidenza, non consegna mai tutto ciò che arriva dal pool di entropia del kernel così come viene, ma viene rimescolato con sha2 o simili e al livello 2 tutto questo, oltre che avvenire con molta più intensità, avviene anche con molta più frequenza (GPG &#34;chiede&#34; spesso bit freschi al kernel) per scongiurare l&#39;eventualità che un attaccante possa prevedere i bit successivi basandosi su quelli passati&#xA;&#xA;Inoltre, GPG salva una parte di questa entropia &#34;pregiata&#34; in ~/.gnupg/randomseed per avere una base di casualità sicura dalle sessioni precedenti nel caso in cui un computer, appena avviato, non avesse ancora accumulato sufficiente entropia.&#xA;&#xA;Si capisce bene come il livello di paranoia di GPG sia fuori scala ma per fortuna tutta questa potenza è totalmente nascosta sotto il cofano di GPG. Infatti per produrre il nostro keyfile binario basta:&#xA;gpg --dev-random 2 4096&#xA;Riepilogo finale&#xA;E dunque, 3 delle 5 modalità sopra descritte, la 2, la 3 e la 5, possono essere ripensate con l&#39;entropia di GPG invee che con quella tipica del kernel.&#xA;2) Keyfile binario&#xA;Kernel entropy&#xA;head -c 4K /dev/urandom   mykey.bin&#xA;&#xA;Libgcrypt entropy&#xA;gpg --dev-random 2 4096 -o mykeygpg.bin&#xA;&#xA;3) Password complessa con caratteri stampabili&#xA;Kernel entropy&#xA;tr -dc &#39;[:graph:]&#39;  /dev/urandom | head -c 4096  mykey.txt&#xA;&#xA;Libgcrypt entropy&#xA;gpg --gen-random 1 10000 | tr -dc &#39;A-Za-z0-9&#39; | head -c 4096   mykeygpg.txt&#xA;&#xA;5) Keyfile binario con openssl&#xA;Kernel entropy&#xA;openssl rand -out mykey.bin 4096&#xA;&#xA;Libgcrypt entropy&#xA;(gpg --gen-random 2 128) | openssl rand -out mykey_gpg.bin -rand /dev/stdin 4096&#xA;&#xA;#entropy #shannon #csprng #password #keyfile #dd #openssl #pwgen #AesCtr #AesNi #sha2 #gpg #bruteforce]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/ffe7c43a6-a8b5f2/hEKmIBrqD2NJ/bA54jpqPlJRapj7UnTRIhqtjGgMEgwrDWtH75WNu.jpg" alt="password"></p>

<p>La generazione di una password o di un keyfile si basa sulla <strong>casualità</strong> ossia sulla capacità del sistema di generare sequenze di simboli non prevedibili.
In questo contesto bisogna avere chiari 3 concetti legati fra loro: <strong>casualità</strong>, <strong>sorgente d&#39;entropia</strong>, <strong>entropia</strong> della password.
</p>
<ul><li><a href="#definizioni-varie" rel="nofollow">Definizioni varie</a></li>
<li><a href="#entropia-del-kernel-csprng" rel="nofollow">Entropia del kernel (CSPRNG)</a></li>
<li><a href="#come-generare-password-e-keyfile" rel="nofollow">Come generare password e keyfile</a>
<ul><li><a href="#analisi" rel="nofollow">Analisi</a></li>
<li><a href="#valutazione" rel="nofollow">Valutazione</a></li>
<li><a href="#conclusione" rel="nofollow">Conclusione</a></li></ul></li>
<li><a href="#bonus-modalit%C3%A0-paranoia" rel="nofollow">Bonus – Modalità paranoia</a>
<ul><li><a href="#generazione-password" rel="nofollow">Generazione password</a></li>
<li><a href="#generazione-keyfile" rel="nofollow">Generazione keyfile</a></li>
<li><a href="#gpg-random" rel="nofollow">GPG Random</a></li></ul></li>
<li><a href="#riepilogo-finale" rel="nofollow">Riepilogo finale</a>
<ul><li><a href="#2-keyfile-binario" rel="nofollow">2) Keyfile binario</a></li>
<li><a href="#3-password-complessa-con-caratteri-stampabili" rel="nofollow">3) Password complessa con caratteri stampabili</a></li>
<li><a href="#5-keyfile-binario-con-openssl" rel="nofollow">5) Keyfile binario con openssl</a></li></ul></li></ul>

<h2 id="definizioni-varie">Definizioni varie</h2>

<p><strong>Casualità</strong>
In generale, posso parlare di <strong>casualità</strong> quando non riesco ad individuare un pattern o un&#39;organizzazione deterministica in una sequenza di dati.</p>

<p>Da un punto di vista crittografico, una sequenza è considerata “casuale” se non esiste un algoritmo che possa prevedere il bit successivo con una probabilità superiore al 50% (puro caso).</p>

<p><strong>Sorgente d&#39;entropia</strong>
La casualità è resa possibile dalla sorgente d&#39;entropia che è il dispositivo o il processo fisico che genera il rumore grezzo per produrre dati casuali. È l&#39;origine dell&#39;incertezza e il suo grado di “purezza” è fondamentale per la produzione della casualità.</p>

<p>Le sorgenti di entropia possono essere fisiche (<strong>TRNG</strong>) o software (<strong>PRNG</strong>). In quest&#39;ultimo caso si parla di <strong>pseudo-casualità</strong> perché si tratta di algoritmi che espandono un seed (un seme) casuale in una sequenza anche arbitrariamente lunga che <strong>sembra</strong> casuale.</p>

<p><strong>Bit di entropia di una sequenza</strong>
O <strong>entropia della sequenza</strong>, è la misura numerica di quanto sia imprevedibile la sequenza casuale di dati.</p>

<p>Quindi:</p>
<ul><li>la <strong>sorgente di entropia</strong> è il nostro <strong>generatore</strong> di incertezza;</li>
<li>la <strong>casualità</strong>, la cui qualità dipende totalmente dalla prima, è il <strong>processo</strong> che produce la sequenza di dati;</li>
<li>l&#39;<strong>entropia</strong>, in termini di bit, che è funzione della lunghezza della sequenza e del set di simboli a disposizione, è la <strong>misura</strong> di quanto la sequenza sia crittograficamente non prevedibile.</li></ul>

<h2 id="entropia-del-kernel-csprng">Entropia del kernel (CSPRNG)</h2>

<p>Su una qualunque linuxbox il protagonista per la generazione dell&#39;entropia necessaria è ovviamente sua maestà il kernel, che è fatto per essere anche un <strong>CSPRNG</strong>, impronunciabile acronimo che sta per <strong>C</strong>ryptographically <strong>S</strong>ecure <strong>P</strong>seudo-<strong>R</strong>andom <strong>N</strong>umber <strong>G</strong>enerator.</p>

<p>Il kernel infatti, già dall&#39;avvio, raccoglie entropia (<strong>entropy harvesting</strong>), rumore casuale direttamente dall&#39;hardware (interrupt del disco, tastiera, mouse, istruzioni CPU come <strong>RDRAND</strong>). Questi dati grezzi vengono mescolati in un serbatoio (l&#39;<strong>entropy pool</strong>) da cui l&#39;algoritmo (<strong>ChaCha20</strong>) pesca per espandere questi dati in un flusso infinito di dati pseudo casuali.</p>

<p>Per avere una misura di quanta casualità abbia il sistema possiamo ricorrere al seguente costrutto:</p>

<pre><code class="language-bash">cat /proc/sys/kernel/random/entropy_avail
</code></pre>

<p>un valore da <strong>256</strong> in poi ci dice abbiamo entropia sufficiente per generare chiavi e quant&#39;altro.</p>

<p>Finita la parte di teoria, vediamo in quanti modi possiamo generare una password bella robusta o un keyfile.</p>

<h2 id="come-generare-password-e-keyfile">Come generare password e keyfile</h2>

<p>Per generare sequenze di dati casuali possiamo seguire 2 vie:</p>
<ol><li>attingere direttamente alla sorgente di entropia fornita dal kernel;</li>
<li>usare la sorgente per prelevare un seme e generare la sequenza casuale via software che è la via di openssl e di pwgen.</li></ol>

<p><strong>Modalità</strong></p>
<ol><li><code>dd if=/dev/urandom of=mykey.bin bs=4096 count=1 iflag=fullblock status=none</code></li>
<li><code>head -c 4K /dev/urandom &gt; mykey.bin</code></li>
<li><code>tr -dc &#39;[:graph:]&#39; &lt; /dev/urandom | head -c 4096 &gt; mykey.txt</code></li>
<li><code>pwgen -s 4095 1 &gt; mykey.txt</code></li>
<li><code>openssl rand -out mykey.bin 4096</code></li></ol>

<h3 id="analisi">Analisi</h3>

<p>Come si comportano questi procedimenti? Proviamo ad analizzarli.</p>

<p><strong>Casualità</strong>
Una prima distinzione va fatta sulla modalità di creazione della casualità.</p>

<p>I primi 3 metodi fanno riferimento direttamente alla sorgente senza introdurre altre stratificazioni software. Sul piano teorico, rappresentano il punto più vicino alla casualità fisica che si possa avere su un computer.</p>

<p><strong>Openssl</strong> e <strong>pwgen</strong> no, sono due <strong>consumatori</strong> per <code>/dev/urandom</code>.
Devono prima pescare un seme da /dev/urandom.
Una volta ottenuto il seme, usano i propri algoritmi (quelli di openssl sono solitamente basati su <strong>AES-CTR</strong> o <strong>SHA2</strong>) per generare una sequenza infinita di numeri casuali.
Pwgen fa una cosa simile ma è stato progettato di base per costruire password pronunciabili (minore entropia intrinseca).</p>

<p><strong>Velocità</strong>
<strong>Openssl</strong>, fra tutti, è il più veloce, soprattutto se si ha l&#39;esigenza di produrre casualità per volumi di decine di giga o di tera.
Ciò è dovuto al fatto che openssl effettua pochissime syscall per prelevare il seme per poi spremere solo la cpu che, supportando quasi certamente le istruzioni hardware <strong>AES-NI</strong>, rende il processo poco impegnativo per la cpu stessa e brutalmene efficiente.
Agire solo sul kernel, pur conservando la purezza della casualità, causa un rallentamento notevole dovuto al grandissimo numero di syscall necessarie e dalla corrispondente attivazione degli algoritmi di cifratura. Inoltre, mentre dd può contare su un buffer relativamente più capiente, cat, tr, head o qualuque altro oggetto che “beva” direttamente da <code>/dev/urandom</code>, hanno dei buffer molto più piccoli a disposizione, 1MB vs 8-16KB, il cui rapporto funge da moltiplicatore sul numero di operazioni necessarie.</p>

<p><strong>Sicurezza</strong>
Tutti i procedimenti indicati, sono estremamente sicuri, anzi, crittograficamente sicuri. Fermo restando che vale sempre l&#39;osservazione fatta sopra sulla metrica dell&#39;entropia di una sequenza casuale: è funzione del set di caratteri e della lunghezza della sequenza. Conti alla mano, con un alfabeto di una settantina di caratteri, una sequenza di almeno 20 caratteri possiederà un&#39;entropia di circa 120 bit che la rendono impenetrabile per gli attuali sistemi di calcolo.</p>

<p>Usare direttamente la sorgente d&#39;entropia, è sicuramente più vantaggioso perché ci fidiamo del kernel.
Inoltre è più isolato perché lavora a livello del kernel dove i processi utente, anche quelli malevoli, non possono accedere alle sue zone di memoria.</p>

<p>Openssl, pwgen e tutti quelli che sono <strong>generatori secondari</strong>, possono incorrere in quella che si diefinisce <strong>duplicazione della casualità</strong>.
Se l&#39;applicazione non è scritta bene, c&#39;è il rischio che il processo, forkandosi, possa “duplicare” la casualità. In sostanza, i processi padre e figlio finiranno per produrre la stessa sequenza di simboli casuali. Una catastrofe.
Vecchie versioni di openssl, ante 1.1.1 per es., hanno sofferto di questa anomalia.</p>

<h3 id="valutazione">Valutazione</h3>

<p>I metodi 1,2,5 producono un keyfile di dati binari, quindi con un entropia enorme quasi vicina all&#39;ottimo teorico.
Come detto, openssl è mostruosamente più veloce.</p>

<p>Volendo essere purista, per un keyfile i metodi 1 e 2 (praticamente equivalenti) sono da preferire.
Per produrre tera di dati casuali (storage, test di rete) sicuramente openssl. Se il volume non dovesse essere esagerato e siamo paranoici, anche il metodo 1 può andare bene.</p>

<p>Per la produzione di una password complessa con simboli stampabili (non necessariamente pronunciabile altrimenti l&#39;entropia sarebbe ancora più bassa) il metodo 3 è da preferire da un punto di vista matematico.</p>

<p>Mettendo da parte openssl che fa comunque un ottimo lavoro (universalmente riconosciuto con tanto di certificazioni FIPS-2), voglio spendere due parole su <strong>pwgen</strong>.
<strong>pwgen</strong>, con il flag <code>-s</code>, crea delle sequenze completamente randomiche su un alfabeto di 62 caratteri.
Se la lunghezza della sequenza è &gt;= 20, e quindi con un&#39;entropia teorica di ~115-120, avremo delle password abbastanza inviolabili dagli attuali sistemi di calcolo.
Usare il flag <code>-y</code> potrebbe sembrare una buona idea perché si forza ad estendere il set di caratteri.
Sicuramente da una parte aumenta l&#39;entropia della sequenza generata, visto che l&#39;alfabeto è molto più vasto. Dall&#39;altra però la forzatura va a compromettere l&#39;uniformità della distribuzione casuale dei simboli.</p>

<h3 id="conclusione">Conclusione</h3>
<ol><li><strong>password/keyfile stampabile</strong>: <code>tr -dc &#39;[:graph:]&#39; &lt; /dev/urandom | head -c [n] &gt; mykey.txt</code></li>
<li><strong>password/keyfile binario</strong>: <code>head -c [n] /dev/urandom &gt; mykey.bin</code> (equivalentemente <code>dd if=/dev/urandom of=mykey.bin bs=4096 count=1 iflag=fullblock status=none</code>)</li>
<li><strong>cancellazione disco</strong>: <code>openssl rand [dim_disco] | dd of=/dev/sdX bs=1M status=progress</code></li></ol>

<h2 id="bonus-modalità-paranoia">Bonus – Modalità paranoia</h2>

<h3 id="generazione-password">Generazione password</h3>

<p>Se non ci fidassimo della sorgente di casualità, possiamo aggiungere alla sorgente di entropia un nostro segreto personale e “mescolarli” attraverso una funzione sha256 o sha512 rendendo il tutto ancora crittograficamente sicuro.</p>

<pre><code class="language-bash">(head -c 4K /dev/urandom ; read -s -p &#34;Per aumentare l&#39;entropia inserisci una frase segreta o premi tasti a caso: &#34; secret) | sha512sum | cut -d&#39; &#39; -f1 &gt; mykey.txt.
</code></pre>

<p>È certamente una password molto robusta per violare la quale occorrerebbe compromettere la sorgente d&#39;entropia e indovinare il segreto personale (<strong>N.B.</strong> stiamo facendo l&#39;ipotesi che si provi a rompere il meccanismo di generazione della chiave non che si provi l&#39;enumerazione attraverso un attacco brute-force).</p>

<h3 id="generazione-keyfile">Generazione keyfile</h3>

<p>Per produrre un keyfile di 4096 bytes con la stessa premessa, faremo uso di openssl.</p>
<ol><li>si genera esplicitamente un seme dalla sorgente di entropia del kernel</li>
<li>come prima, con sha2 si mescola  il seme con un nostro segreto</li>
<li>si dà in pasto ad openssl.</li></ol>

<pre><code class="language-bash"># Creiamo un seme unico mescolando /dev/urandom e il mio input con sha512
# Usiamo quel seme per generare 4KB di dati casuali &#34;espansi&#34;
(head -c 256 /dev/urandom; read -s -p &#34;Per aumentare l&#39;entropia inserisci una frase segreta o premi tasti a caso: &#34; secret; echo &#34;$secret&#34;) | sha512sum | cut -d &#34; &#34; -f1 | openssl enc -aes-256-ctr -pbkdf2 -pass stdin -nosalt -in /dev/zero | head -c 4096 &gt; mykey.bin
</code></pre>

<p>L&#39;errore che compare alla fine è un falso negativo, dovuto al fatto che openssl sta ancora provando a scrivere dati e <code>head</code> li tronca all&#39;improvviso.</p>

<p>Giusto due righe di spiegazione:</p>
<ol><li><code>head -c 256 /dev/urandom</code>: preleva un po&#39; di dati casuali “puri”</li>
<li><code>read -sp secret</code>: si inserisce una password, una frase o tasti schiacciati a caso per aumentare l&#39;entropia</li>
<li><code>sha512sum | cut -d &#34; &#34; -f1</code>: si mescola tutto e si preleva solo l&#39;esadecimale di 64 bytes</li>
<li><code>openssl enc -aes-256-ctr -pbkdf2 -pass stdin -nosalt -in /dev/zero</code>: openssl, che riceve il seme sullo stdin, fa la sua magia producendo un fiume di dati casuali</li>
<li><code>head -c 4096</code>: tronca il “fiume” alla lunghezza voluta per il nostro keyfile</li></ol>

<p>Quindi:</p>
<ol><li><strong>Contro i bug del kernel</strong>: se la nostra sorgente d&#39;entropia fosse compromessa e diventasse deterministica, occorrerebbe comunque conoscere il nostro segreto</li>
<li><strong>Contro il keylogging</strong>: anche se il nostro segreto potesse essere svelato, la sorgente d&#39;entropia garantirebbe comunque l&#39;inviolabilità della nostra password</li></ol>

<h3 id="gpg-random">GPG Random</h3>

<p>Quando si parla di paranoia, un altro ottimo candidato per produrre password e keyfile è certamente <strong>GPG</strong>.
GPG non si llimita a copiare dati da <code>/dev/urandom</code> ma utilizza una propria libreria crittografica chiamata <strong>Libgcrypt</strong>, che implementa un generatore di numeri pseudocasuali, crittograficamente sicuro, molto sofisticato.</p>

<p>A differenza di ciò che abbiamo visto finora, GPG permette di impostare un livello di qualità per la casualità da produrre.</p>
<ol><li><strong>livello 0 (Debole)</strong>: per scopi didatti, usato raramente.</li>
<li><strong>livello 1 (Avanzato)</strong>: adatto per chiavi di sessione e cifratura standard. Corrisponde ad una casualità di alta qualità</li>
<li><strong>livello 2 (Forte)</strong>: utilizzato per le chiavi a lungo termine (le chiavi private di GPG). È un livello estremamente conservativo. Se GPG valuta di non avere entropia sufficientemente fresca, si mette in attesa.</li></ol>

<p>GPG non si fida ciecamente del kernel e così <strong>Libgcrypt crea un proprio pool di entropia</strong> in user space.</p>
<ol><li>Libgcrypt pesca al solito un seme da <code>/dev/urandom</code></li>
<li>il seme viene rimescolato con sha2 o aes</li>
<li>per evitare che i dati casuali finiscano sullo swap, libgcrypt usa <strong>pagine di memoria protetta</strong> (<strong>mlock</strong>)</li></ol>

<p>Impostando il livello 2, libgcrypt può decidere di scartare molti più dati se ritiene che il pool di entropia non sia abbastanza “fresco”. Inoltre, in virtù della sua diffidenza, <strong>non consegna mai</strong> tutto ciò che arriva dal pool di entropia del kernel così come viene, ma viene rimescolato con sha2 o simili e al livello 2 tutto questo, oltre che avvenire con molta più intensità, avviene anche con molta più frequenza (GPG “chiede” spesso bit freschi al kernel) per scongiurare l&#39;eventualità che un attaccante possa prevedere i bit successivi basandosi su quelli passati</p>

<p>Inoltre, GPG salva una parte di questa entropia “pregiata” in <code>~/.gnupg/random_seed</code> per avere una base di casualità sicura dalle sessioni precedenti nel caso in cui un computer, appena avviato, non avesse ancora accumulato sufficiente entropia.</p>

<p>Si capisce bene come il livello di paranoia di GPG sia fuori scala ma per fortuna tutta questa potenza è totalmente nascosta sotto il cofano di GPG. Infatti per produrre il nostro keyfile binario basta:</p>

<pre><code class="language-bash">gpg --dev-random 2 4096
</code></pre>

<h2 id="riepilogo-finale">Riepilogo finale</h2>

<p>E dunque, 3 delle 5 modalità sopra descritte, la 2, la 3 e la 5, possono essere ripensate con l&#39;entropia di GPG invee che con quella tipica del kernel.</p>

<h3 id="2-keyfile-binario">2) Keyfile binario</h3>
<ul><li><p><strong>Kernel entropy</strong></p>

<pre><code class="language-bash">head -c 4K /dev/urandom &gt; mykey.bin
</code></pre></li>

<li><p><strong>Libgcrypt entropy</strong></p>

<pre><code class="language-bash">gpg --dev-random 2 4096 -o mykey_gpg.bin
</code></pre></li></ul>

<h3 id="3-password-complessa-con-caratteri-stampabili">3) Password complessa con caratteri stampabili</h3>
<ul><li><p><strong>Kernel entropy</strong></p>

<pre><code class="language-bash">tr -dc &#39;[:graph:]&#39; &lt; /dev/urandom | head -c 4096 &gt; mykey.txt
</code></pre></li>

<li><p><strong>Libgcrypt entropy</strong></p>

<pre><code class="language-bash">gpg --gen-random 1 10000 | tr -dc &#39;A-Za-z0-9&#39; | head -c 4096 &gt; mykey_gpg.txt
</code></pre></li></ul>

<h3 id="5-keyfile-binario-con-openssl">5) Keyfile binario con openssl</h3>
<ul><li><p><strong>Kernel entropy</strong></p>

<pre><code class="language-bash">openssl rand -out mykey.bin 4096
</code></pre></li>

<li><p><strong>Libgcrypt entropy</strong></p>

<pre><code class="language-bash">(gpg --gen-random 2 128) | openssl rand -out mykey_gpg.bin -rand /dev/stdin 4096
</code></pre></li></ul>

<p><a href="/aytin/tag:entropy" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">entropy</span></a> <a href="/aytin/tag:shannon" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">shannon</span></a> <a href="/aytin/tag:csprng" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">csprng</span></a> <a href="/aytin/tag:password" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">password</span></a> <a href="/aytin/tag:keyfile" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">keyfile</span></a> <a href="/aytin/tag:dd" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dd</span></a> <a href="/aytin/tag:openssl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">openssl</span></a> <a href="/aytin/tag:pwgen" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">pwgen</span></a> <a href="/aytin/tag:AesCtr" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">AesCtr</span></a> <a href="/aytin/tag:AesNi" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">AesNi</span></a> <a href="/aytin/tag:sha2" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">sha2</span></a> <a href="/aytin/tag:gpg" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gpg</span></a> <a href="/aytin/tag:bruteforce" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">bruteforce</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/come-generare-una-password-o-un-keyfile-sicuri-trilogia-della-password-1-di</guid>
      <pubDate>Mon, 12 Jan 2026 14:39:55 +0000</pubDate>
    </item>
  </channel>
</rss>