Sicurezza trasmissione GPRS

Buonasera.

Arrivo subito al dunque…

Ho implementato un piccolo script in PHP che “raccoglie” i dati da alcuni sensori che trasmetto via URL tramite un GPRS collegato ad Arduino per poi riversarli in mySQL.

…funziona!

Dal punto di vista della “sicurezza” all’interno dello script in PHP eseguo controlli circa la consistenza e la completezza dei dati che mi aspetto di ricevere. E’ sufficiente?

Esiste un modo per stabilire chi è che trasmette i dati? (IMEI del GPRS, numero della SIM, ecc…).

Ringrazio.
Ciao, G.

Ti dico come facevo io per un'altra applicazione ...
... usavo un algoritmo mio (data + tempo + un pezzo di ciò che si trasmette, ecc) per creare un qualche cosa di cui poi calcolavo il CRC32 e trasmettevo quello assieme a tutti i dati. Chi riceveva applicava lo stesso calcolo e verificava che il CRC32 fosse lo stesso ... se lo era il messaggio era buono, se non lo era, si scartava.

Non è certamente il massimo della sicurezza, ma è sufficientemente complesso da tenere alla larga i rompiscatole ... :smiley:

Guglielmo

P.S.: Nota che ci deve essere qualche cosa che varia (io usavo data/tempo) in modo che anche lo stesso messaggio comunque NON genera mai lo stesso CRC32 :wink:

Ok, ho capito la logica, ora devo vedere cosa riesco a mettere insieme.

Per il "tempo" forse si riuscirà ad utilizzare solo le "ore" viste le difficoltà nell'allineare gli orologi di arduino/GPRS con quello del web server (di mezzo ci sono pure i tempi per la trasmissione che sono comunque molti secondi).

Ci medito.
Grazie.
Ciao, G.

...se puoi allungare un po' il colloquio tra i due, allora potresti fare che il pimo richiede al server un numero random, il server glie lo invia e il primo costruisce il blocchetto segreto con quel numero che entrambi conoscono e che, anche se viene intercettato, è ininfluente, dato che: primo NON si sa l'algoritmo che usi e dove infili quel numero; secondo tu comunque invii un CRC32 dal quale non si risale al messaggio generatore :wink:

Ovvio, si complica un po' il protocollo (io per un'altra applicazione l'ho fatto), ma si eliminano i problemi di sincronizzazione temporale (anche se, ormai, richiedere il tempo tramite NTP è banale) :slight_smile:

Guglielmo

ok grazie, vedo di fare un pò di prove. Magari spedisco in coda ai dati dei sensori anche l'orario dell'invio, così anche il web server banalmente "lavora" sullo stesso orario.

Grazie
Ciao, G.

Niente…
mi sono arenato sul CRC32.

Partendo dall’omonima libreria ho messo insieme queste tre righe di codice:

// Funzione per creare il CRC32 di una stringa
// necessario alla verifica dei dati trasmessi
// Esempio CRC32 di "Hello World" è "0x4A17B156" in HEX
// Esempio CRC32 di "Hello World" è "1243066710" in DEC

void creaCRC32(){
  
  uint8_t StringaToCRC32[] = "Hello World";
  
  // Calcola checksum un byte alla volta
  size_t numBytes = sizeof(StringaToCRC32)-1;

  // Aggiungi ogni byte alla checksum
  for (size_t i = 0; i < numBytes; i++){
    myCRC32.update(StringaToCRC32[i]);
  }

  // Genera la checksum finale
  uint32_t checksum = myCRC32.finalize();

  Serial.println(checksum,HEX);
  Serial.println(checksum,DEC);
  
} // Fine creaCRC32

Il codice funziona, tuttavia la variabile di partenza che vorrei utilizzare per creare il “checksum” è una char, e sinceramente non ho idea da dove iniziare per adeguare il codice… Qualche indizio?

Grazie
Ciao, G.

Infatti devi usare un stringa classica del ‘C’, ovvero un array di char …
… nell’esempio che hai messo è praticamente la stringa che lui salva nella variabile: StringaToCRC32, che è un array di uint8_t che puoi benissimo lasciare come tali o usare il tipo char.

Guglielmo

Ok, soluzione semplice…
Ho modificato

uint8_t StringaToCRC32 = “Hello World”;

con

char StringaToCRC32 = “Hello World”;

e funziona. Ero convinto che fosse necessario convertire l’array char in array int.

Volendo ora fare un passettino in più, ossia creare una funzione che accetta come input la stringa di cui calcolare il CRC32 ed ottenere il checksum come output, ho scritto quanto segue, ma devo aver scritto qualcosa di errato dato che il risultato atteso non è corretto. E’ sbagliata la sintassi della funzione?

char pippo[]="Hello World";

void setup(){

      Serial.println(creaCRC32(pippo));
}


uint32_t creaCRC32(char* StringaToCRC32){
    
  // Calcola checksum un byte alla volta
  size_t numBytes = sizeof(StringaToCRC32)-1;

  // Aggiungi ogni byte alla checksum
  for (size_t i = 0; i < numBytes; i++){
    myCRC32.update(StringaToCRC32[i]);
  }

  // Genera la checksum finale
  uint32_t checksum = myCRC32.finalize();

  return checksum; 
  
}

JulianusGM:
... dato che il risultato atteso non è corretto. E' sbagliata la sintassi della funzione?

... in che senso "il risultato atteso non è corretto"? Con cosa lo confronti?

Guglielmo

Lo confronto con il CRC32 che avevo calcolato con il codice del post #5 dato che la stringa di partenza è la medesima. Sbaglio?

Ah .. ok ... in effetti dovrebbe dare lo stesso risultato ... ::slight_smile:

Non conosco quella libreria (io mi sono scritto un modulo in C) ... non è che c'è una funzione da chiamare all'inizio per "azzerare" il conteggio in partenza? Perché, se la devo chiamare due volte, come faccio a dirgli che è iniziato un nuovo calcolo?

Guglielmo

Guardando le keywords della libreria sembrerebbe di no. Temo però che sia un problema di sintassi dato che cambiando il contenuto di pippo il risultato non cambia.
Vabbè ci guarderò domani... stasera do' i numeri...

Ciao, G.

... solo per prova metti globale "checksum" ed inizializzalo a zero prima di chiamare la funzione :wink:

Guglielmo

Ho provato, ma dà lo stesso identico risultato errato. Bho...non capisco...
Mi sa che utilizzerò la funzione void() funzionante senza questa finezza.

G.

Mmmm . strano, c’è qualche cosa che mi sfugge …
… comunque, elimina la libreria che stai usando; in allegato un .c ed u .h, mettili nella cartella del tuo progetto, includi il file crc32.h nel tuo programma e usa la seguente sintassi:

...
#include "crc32.h"
...
unsigned long myCrc32;
char miaStringa[] = "testo di prova";
...
...
myCrc32 = calc_crc32(miaStringa, sizeof(miaStringa));
...

… vedi se ti funziona bene :wink:

Guglielmo

CRC32.zip (2.21 KB)

Mi sono permesso di modificare

myCrc32 = calc_crc32(miaStringa, sizeof(miaStringa));

con

myCrc32 = calc_crc32(miaStringa, sizeof(miaStringa)-1);

Così funziona.
Grazie mille.
G.

... giusto, occorre passare il numero do caratteri validi su cui calcolare il CRC e quindi ... occorre eliminare il 0x00 finale della stringa :smiley:

E' che l'ho scritto un sacco di tempo fa e manco mi ricordo come funziona :smiley: :smiley: :smiley:

Guglielmo

P.S.: Se occorre, a suo tempo, avevo fatto anche CRC16 e CRC8 :wink:

Per il momento mi basta questo.
Grazie mille.
Ciao, G.

Ok ... comunque, anche su fai "myCrc32 = calc_crc32(miaStringa, sizeof(miaStringa));" è la stessa cosa ... il valore che ottieni è ovviamnete diverso perché fa rientrare nel calcolo anche lo 0x00 finale, ma NON è che sia errato, anzi ... in fin dei conti è anche lui parte di quell'array :wink:

Guglielmo

P.S.: ... considera poi che NON siste UN CRC32, ma esistono vari metodi che sono funzione del "polinomio generatore", quindi un programma potrebbe darti un certo valore, un altro un altro valore ... l'importante è usare sempre lo stesso codice con lo stesso "polinomio generatore" (... ovvero tutti quei valori che vedi nel sorgente).