Ho pensato un po'
rimanendo su cose semplici, da fare capire e spiegare, si potrebbe fare così:
parte radio: in chiaro, con moduli HC12, la cifratura la facciamo noi
cifratura, prima ipotesi
la teoria dice che una chiave sufficentemente lunga e usata una volta sola rende virtualmente indecrittabile il messaggio senza usare metodi a forza bruta
ho pensato che una semplice cifratura con uno xor bit a bit, primo carattere del messaggio xor col primo della chiave, secondo col secondo e via così risulta quindi inviolabile, se cambiamo la chiave tutte le volte
OK, ci pensiamo dopo, per ora il problema è che ci sono casi per cui la cifratura del carattere darebbe come risultato \0, che non vogliamo perchè ci troncherebbe la stringa (intesa come stringa di C terminata da \0)
ok, la funzione di cifratura carattere per carattere EVITA questo caso, brutalmente
char codex(char a, char b)
{
// applica una semplice codifica xor al byte in ingresso
// per evitare che diventi \0 (terminatore di stringa)
// NON applica la codifica se a==b
// passo per una funzione apposita solo per prevedere eventuali agggiunte
if (a == b)
{
return a;
}
else
{
return a ^ b;
}
}
queso permette di cifrare un carattere per volta
cifrare un intera stringa potrebbe essere
void cifra(char stringa[], const char chiave[], byte index)
{
// cifra una stringa (intesa come array di char terminato da \0
int indice = 0;
while (stringa[indice])
{
// fino alla fine della stringa
byte partizione = index + indice;
stringa[indice] = codex(stringa[indice++], chiave[partizione]);
}
}
ignoriamo per il momento index e partizione, servono dopo
questa funzione cifra una stringa su se stessa usando una chiave lunga almeno la lunghezza della stringa, soddisfacendo la teoria
la cifratura è simmetrica, per de-cifrare basta che in ricezione si ripeta l'operazione con la giusta chiave
il problema è cambiare la chiave tutte le volte, sulle due macchine
OK, si risolve, si usa una chiave lunga 255 caratteri (e se il messsaggio fosse più lungo NON userei arduino)
e si comincia tutte le volte a leggerla da un differente punto di ingresso
ecco quindi index inteso come punto di ingresso della chiave e partizione inteso come il punto fin dove siamo arrivati nell'uso della chiave, cast(r)are a byte permette di "andare a capo" e ripartire dall'inizio della chiave se si sborda come lunghezza
adesso serve solo scambiarsi tra trasmettitore e ricevitore (in letteratura solitamente indicati come Alice e Bob, con Charlie che fa il man in the middle)
dicevo che Alice e Bob devono solo scambiarsi l'indice, che cambia tutte le volte
OK, basta che Alice trasmetta una stringa conosciuta, e Bob tenti la decifratura con i primi N indici successivi all'ultimo usato, se la decodifica va a buon fine sappiamo quale indice ha usato Alice e possiamo usarlo per decifrare il messaggio principale
ecco, quindi come procedere:
Alice guarda l'ultimo indice usato, passa all'indice successivo e lo usa per cifrare la password, trasmette la password, aspetta il tempo che Bob faccia il lavoro e trasmette con la stessa cifratura il messaggio
Bob riceve la password cifrata e ripete per ogni indice, dall'ultimo che ha usato fino al ennesimo successivo, la decifrazione, se va a buon fine aggiorna l'ultimo indice usato e decifra il messaggio, che nel frattempo Alice sta per trasmettergli, se non va a buon fine non decifra nulla e morta li
Punti deboli: due
- messa così la cosa sembra che la chiave venga usata per tronconi successivi e sovrapponentisi, che NO buono NO
2)se Charlie viene a conoscenza della password in chiaro la puo' usare per ricostruire la chiave, o almeno il pezzo locale appena usato, che potrebbe usare per ri-costruire a blocchi l'intera chiave
risolviamo prima questo: basta che invece di una sola password ve ne siano alcune, che verranno usate in ordine sparso e casuale, mai la stessa due volte consecutive, questo riduce drasticamente la possibilità che Charlie possa ricostruire prima la password e poi da questa la chiave
invece per il primo problema, è un non problema: io non ho mai detto che l'indice si deve incrementare di uno per ogni utilizzo
basta che dato un indice sia possibile conoscerne il successivo, che non sia banalmente quello ottenuto fecendo +1
magari facendo +101 e cast(r)ando a byte si ottiene che la sequenza degli indici usati NON sia consecutiva e non capiti mai che due messaggio consecutivi abbiano due chiavi locali uguali per tutto salvo il carattere di inizio
quindi una funzione byte successivo(byte i) restituirebbe l'indice da usare immeditamente dopo i, pur se quseto NON è banalmente i+1
credo di aver descritto l'intera procedura di cifratura/de-cifratura con una sicurezza accettabile per le applicazioni di classe "arduino"
di quelle classe "B52" non parlo, per clausole contrattuali