MIGLIORAMENTO SOSTANZIALE DEL METODO DI GENERAZIONE DI CHIAVI/PASSWORD AD ENTROPIA REALE
Purtroppo sono stato vittima di un piccolo incidente domestico (ah l'età) e quindi nel weekend ho avuto modo, seppur a mobilità ridotta, di riprendere alcuni progettini/passatempo tra cui rivedere il generatore di chiavi o password ad entropia reale.
Mi interessava uscire dal loop di poter raggiungere un livello di entropia che si avvicinasse quanto più possibile a quella teorica, in modo da avere una chiave o password quanto più perfetta. La soluzione mi è arrivata quando mi sono messo in ambiente Linux a ragionare sulle soluzioni e sul perchè Linux mi resituisse un valore enormemente migliore, uno scostamento del genere non poteva essere solo dovuto al sistema operativo.
Dopo la creazione di questo thread e le valutazioni in Linux, mi sono sorti dei dubbi legati alla funzione che ho utilizzato: time.perf_counter_ns() la quale introduce certamente una buona quota di entropia, però nel valore di 10000 letture dei valori di entropia (equivalente a 10000 lanci di dadi) si trovava il problema che abbassava l'entropia reale ed aumentava il gap da quella teorica. Infatti aumentando il range da 10k a 100k (ad esempio) l'entropia calava e questo non mi dava pace. Il problema è dovuto al fatto che così tante letture in poche frazioni di secondo portavano ad avere molti numeri uguali; aumentando le letture a 100k si avevano una enormità di letture uguali; portando ad un crollo entropico.
Di seguito soluzione per Windows e per Linux, con spiegazione.
Questo permette di avere entropia REALE circa uguale a quella TEORICA. Il metodo è ottimo per generare Password, chiavi private PGP e le PASSPHRASE per dei vostri wallet!!
SOLUZIONE WINDOWS (via Powershell con ambiente python attivabile come da primo post):La soluzione principale sta nel cambiare tipo di funzione, quindi mi sono concentrato su CSPRNG che permette di registrare dati sul rumore termico del processore, latenza dei sistemi I/O, Jitter degli orologi hardware, ecc. Tutto questo viene successivamente crittografata ed elaborata per creare un valore enorme di bit indistinguibili dai dati reali registrati, aumentando l'entropia in maniera sensibile.
Linux su questo fa un campionamento in automatico ogni 60 secondi, Windows non l'ho capito se lo fa anch'esso casuale o a richiesta.
Quindi, da Powershell, attivate anaconda o miniconda come da primo post del thread, quindi copiate lo script che segue:
python -c "import secrets,string,math;
chars=string.ascii_letters+string.digits+chr(33)+chr(64)+chr(35)+chr(36)+chr(37)+chr(94)+chr(38)+chr(42)+chr(40)+chr(41);
pw=''.join(secrets.choice(chars) for _ in range(16));
print(pw); print(f'# {16*math.log2(len(chars)):.1f} bits')"
Quindi nella prima stringa
python -c "import secrets,string,math;
importa il modulo di CSPRNG che è il cuore del discorso;
importa gli alfabeti ASCII (visibile nella seconda riga - con i codici dei caratteri speciali e non più come nel precedente dove l'alfabeto lo inserivo io)
il modulo math per il calcolo dell'entropia REALE (riga print) sulla password generata nella penultima stringa (pw).

Nell'immagine avrete la password di 16 caratteri e l'entropia REALE corrispondente.
SOLUZIONE LINUX (Via Bash o console classica)Linux come detto sopra ha un aggiornamento ogni 60 secondi del rumore generato dall'hardware del PC e permette quindi di non averlo a chiamata ma sempre disponibile, questo perchè la raccolta dei dati RDRAND è nativo nei sistemi Linux.
Infatti la funzione /dev/urandom va proprio a predere questo dato.
Aprite il bash o console di Linux e copiate:
n=16
pw=$(tr -dc 'a-zA-Z0-9!@#$%^&*()' < /dev/urandom | head -c $n)
echo "$pw"
echo "# $n chars, ~$(python3 -c "import math; print(f'{$n * math.log2(72):.1f}')") bits"
la prima riga definisce la lunghezza della password o chiave
la seconda riga permette di generare la password andando a leggere e catturare tramite /dev/urandom il CSPRNG del kernel linux i primi 16 byte raccolti e crittografati all'origine e ve li fa vedere nell'interfaccia con la terza riga.
La quarta riga calcola l'entropia Reale della password.

Anche qui la password con la sua entropia.
CONSIDERAZIONIIl metodo per calcolare l'entropia è sempre basato sull'algoritmo di Shannon, ma ho cambiato punto di vista.
Con il codice vecchio facevo una stima empirica sulla distribuzione, mentre con questo nuovo script la distribuzione è assunta come uniforme con pari probabilità per ognuno dei 72 caratteri e quindi l'entropia è calcolata con il classico n*log2(72), però questa volta reale è uguale al teorico.
Qualora doveste produrre password per PASSPHRASE di wallet o per CHIAVI PGP vi consiglio di riavvire il vostro pc (non spegnere, ma riavviare) e metterlo offline prima di procedere alla generazione.