Sommario:
- Forniture
- Passaggio 1: 1. Configurare Atecc608a
- Fase 2: 2. Progettazione del circuito (master e slave)
- Passaggio 3: 3. il Codice (Slave e Master)
- Passaggio 4: 4. Vai oltre
- Passaggio 5: conclusione
Video: Comunicazione crittografata wireless Arduino: 5 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:01
Ciao a tutti, In questo secondo articolo ti spiegherò come utilizzare il chip Atecc608a per proteggere la tua comunicazione wireless. Per questo, userò NRF24L01+ per la parte Wireless e Arduino UNO.
Il microchip ATECC608A è stato progettato da MicroChip e dispone di molteplici strumenti di sicurezza. Ad esempio, questo chip può memorizzare chiavi ECC, chiavi AES (per AES 128) e hash SHA2.
L'articolo: NRF24L01 + Arduino UNO + ATECC608A
Durante una comunicazione tra due oggetti IoT, possono esistere più attacchi: Man Of the mild, Copy of information e altro.. Quindi la mia idea è molto semplice:
- Utilizzo di dati crittografati tra due o più oggetti IoT.
- Forniture a basso costo
- Può funzionare con un Arduino UNO
Nel mio caso, io uso
- l'Atecc608a per memorizzare la mia chiave AES e per crittografare/decrittografare i miei dati.
- l'Arduino Uno come Microcontrollore
- Il NRF24L01 per inviare i miei dati
Devi seguire questi passaggi per questo progetto:
- Configura il chip ATECC608A
- Eseguire il circuito (Master Node e Slave Node)
- Codice parte
- Vai oltre!
Per i primi passi "Configura il chip ATECC608A", ho scritto un altro articolo che spiega ogni passaggio in ordine. Il link è qui:
Ora inizia!
Forniture
Per questo progetto hai bisogno di:
- 2 Arduino UNO o Arduino NANO o Arduino Mega
- Un po' di filo
- 2 Atecc608a (ciascuno costa meno di 0,60$)
- 2 NRF24L01+
- 2 condensatori (10 μF)
- taglieri
Link al mio articolo che spiega come configurare il chip ATECC608A -> Come configurare Atecc608a
Passaggio 1: 1. Configurare Atecc608a
Non descriverò in dettaglio tutti i passaggi da seguire per configurare un ATECC608A perché ho scritto un articolo completo che spiega tutti i passaggi per farlo. Per configurarlo è necessario seguire lo "Step 4" di questo articolo chiamato "2. Configurazione del Chip (Atecc608a)"
Il link è: Come configurare un ATECC608A
Inoltre, devi mettere la stessa configurazione per l'Atecc608a, lato master e lato slave, altrimenti non sarai in grado di decifrare i tuoi dati
Avvertimento:
Per configurare questo chip, devi seguire tutti i passaggi dell'articolo sopra in ordine. Se manca un passaggio o il chip non è bloccato, non sarai in grado di eseguire questo progetto
Resto:
Passaggio da seguire per questo:
- Crea un modello di configurazione
- Scrivi questo modello sul chip
- Blocca la zona di configurazione
- Scrivi la tua chiave AES (128 bit) in uno slot
- Blocca l'area dati
Fase 2: 2. Progettazione del circuito (master e slave)
In questo progetto, avrai un nodo master e un nodo slave.
Il nodo master stamperà in chiaro i dati inviati dal nodo slave. Richiederà dati dal nodo slave ogni X volte.
Il nodo slave ascolterà la "rete" e quando riceverà un "Richiesta dati", lo genererà, lo crittograferà e lo invierà al nodo master.
Per entrambi i lati, master e slave il circuito è lo stesso:
- Un arduino Nano
- Un ATECC608A
- Un NRF24L01
Ho collegato il circuito a questo passaggio (vedi immagine sopra).
Per l'ATECC608A per Arduino UNO, questo è un 8 pin soic. Ho aggiunto la "vista dall'alto" sopra:
- ARDUINO 3.3V -> PIN 8 (Atecc608a)
- ARDUINO GND -> PIN 4 (Atecc608a)
- ARDUINO A4 (SDL) -> PIN 5 (Atecc608a)
- ARDUINO A5 (SCL) -> PIN 6 (Atecc608a)
Per NRF24L01 ad Arduino:
- ARDUINO 3.3V -> VCC (nrf24l01)
- ARDUINO GND -> GND (nrf24l01)
- ARDUINO 9 -> CE (nrf24l01)
- ARDUINO 10 -> CSN (nrf24l01)
- ARDUINO 11 -> MOSI (nrf24L01)
- ARDUINO 12 -> MISO (nrf24l01)
- ARDUINO 13 -> SCK (nrf24l01)
- ARDUINO 3 -> IRQ (nrf24l01) -> solo per nodo Slave, non utilizzato in modalità Master
Perché usare il pin IRQ di NRF24L01
Il pin IRQ è molto utile, questo pin permette di dire (LOW) quando un pacchetto viene ricevuto dall'NRF24L01, quindi possiamo collegare un Interrupt a questo pin per svegliare il nodo slave.
Passaggio 3: 3. il Codice (Slave e Master)
Nodo Schiavo
Uso il risparmio energetico per il nodo slave perché non ha bisogno di ascoltare tutto il tempo.
Come funziona: il nodo slave ascolta e aspetta di ricevere un "pacchetto Wake UP". Questo pacchetto viene inviato dal nodo Master per richiedere dati allo slave.
Nel mio caso uso un array di due int:
// Pacchetto Wake UP
const int wake_packet[2] = {20, 02};
Se il mio nodo riceve un pacchetto,
- si sveglia, leggi questo pacchetto, se il pacchetto è un "Wake UP",
- genera i dati,
- crittografare i dati,
- inviare i dati al master, attendere un pacchetto ACK,
- dormire.
Per la crittografia AES, utilizzo una chiave nello slot numero 9.
Questo è il mio codice per il nodo Slave
#include "Arduino.h"#include "avr/sleep.h" #include "avr/wdt.h"
#include "SPI.h"
#include "nRF24L01.h" #include "RF24.h"
#include "Wire.h"
// Libreria ATECC608A
#include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h"
#define ID_NODE 255
#define AES_KEY (uint8_t)9
ATCAIfaceCfg cfg;
stato ATCA_STATUS;
radio RF24 (9, 10);
const uint64_t masteraddresse = 0x11111111111;
const uint64_t slaveaddresse = 0x1111111100;
/**
* \brief Funzione eseguita quando l'interrupt è impostato (IRQ LOW) * * */ void wakeUpIRQ() { while (radio.available()) { int data[32]; radio.read(&data, 32); if (data[0] == 20 && data[1] == 02) { float temp = 17,6; ronzio galleggiante = 16,4;
uint8_t dati[16];
uint8_t dati cifrati[16];
// Costruisci una stringa per impostare tutto il mio valore
// Ogni valore è separato da un "|" e "$" indica la fine dei dati // ATTENZIONE: deve essere inferiore a 11 di lunghezza String tmp_str_data = String(ID_NODE) + "|" + Stringa(temp, 1) + "|" + Stringa(ronzio, 1) + "$"; //dimensione di 11 Serial.println("tmp_str_data: " + tmp_str_data);
tmp_str_data.getBytes(data, sizeof(data));
// Cripta i dati
ATCA_STATUS status = aes_basic_encrypt(&cfg, data, sizeof(data), cypherdata, AES_KEY); if (status == ATCA_SUCCESS) { long rand = random((long)10000, (long)99999);
// genera un UUID basato sui primi tre numeri = nodo ID
String uuid = String(ID_NODE) + String(rand); // Dimensione di 8
uint8_t tmp_uuid[8];
uint8_t data_to_send[32];
uuid.getBytes(tmp_uuid, sizeof(tmp_uuid) + 1);
memcpy(data_to_send, tmp_uuid, sizeof(tmp_uuid));
memcpy(data_to_send + sizeof(tmp_uuid), cypherdata, sizeof(cypherdata)); // Interrompi l'ascolto radio.stopListening();
bool rslt;
// Invia dati rslt = radio.write(&data_to_send, sizeof(data_to_send)); // Inizia ad ascoltare radio.startListening(); if (rslt) { // Fine e modalità di sospensione Serial.println(F("Fatto")); } } } } }
configurazione nulla()
{ Serial.begin(9600);
// Inizia il costruttore per la libreria
cfg.iface_type = ATCA_I2C_IFACE; // Tipo di comunicazione -> Modalità I2C cfg.devtype = ATECC608A; // Tipo di chip cfg.atcai2c.slave_address = 0XC0; // indirizzo I2C (valore predefinito) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Ritardo di risveglio (1500 ms) cfg.rx_retries = 20;
radio.begin();
radio.setDataRate(RF24_250KBPS); radio.maskIRQ(1, 1, 0); radio.enableAckPayload(); radio.setRetries(5, 5);
radio.openWritingPipe(masteraddresse);
radio.openReadingPipe(1, slaveaddresse); // Collega l'interrupt al pin 3 // Modifica 1 con O se vuoi l'interrupt al pin 2 // FALLING MODE = Pin at LOW attachInterrupt(1, wakeUpIRQ, FALLING); }
ciclo vuoto()
{ // Non c'è bisogno }
Nodo principale
Il nodo master si sveglia ogni 8 secondi per chiedere dati al nodo slave
Come funziona: Il nodo master invia un pacchetto "WakeUP" allo slave e dopo attende una risposta dello slave con i dati.
Nel mio caso uso un array di due int:
// Pacchetto Wake UP
const int wake_packet[2] = {20, 02};
Se il nodo slave invia un pacchetto ACK dopo che il master ha inviato un pacchetto WakeUp:
- Master impostato in modalità Listen e attendere una comunicazione
- Se la comunicazione
- Estrai il primo byte 8, saccheggia i primi tre byte degli 8 byte, se questo è il nodo ID
- Estrai i 16 byte di cifratura
- Decifra i dati
- Stampa i dati in Seriale
- Modalità risparmio
Per la crittografia AES, utilizzo una chiave nello slot numero 9.
Questo è il mio codice per il nodo Master
#include "Arduino.h"
#include "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // Libreria ATECC608A #include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h" #define ID_NODE 255 #define AES_KEY (uint8_t)9 ATCAIfaceCfg cfg; stato ATCA_STATUS; radio RF24 (9, 10); const uint64_t masteraddresse = 0x11111111111; const uint64_t slaveaddresse = 0x1111111100; // Pacchetto Wake UP const int wake_packet[2] = {20, 02}; // watchdog interrupt ISR(WDT_vect) { wdt_disable(); // disabilita watchdog } void sleepmode() { // disabilita ADC ADCSRA = 0; // cancella vari flag di "reset" MCUSR = 0; // consenti le modifiche, disabilita il ripristino WDTCSR = bit(WDCE) | bit(WDE); // imposta la modalità di interruzione e un intervallo WDTCSR = bit(WDIE) | bit(WDP3) | bit(WDP0); // imposta WDIE e 8 secondi di ritardo wdt_reset(); // resetta il watchdog set_sleep_mode(SLEEP_MODE_PWR_DOWN); noInterrupt(); // la sequenza a tempo segue sleep_enable(); // disattiva l'abilitazione del brown-out nel software MCUCR = bit(BODS) | bit(BODSE); MCUCR = bit(BODS); interrompe(); // garantisce l'esecuzione dell'istruzione successiva sleep_cpu(); // annulla il sonno per precauzione sleep_disable(); } void setup() { Serial.begin(9600); // Inizia il costruttore per la libreria cfg.iface_type = ATCA_I2C_IFACE; // Tipo di comunicazione -> Modalità I2C cfg.devtype = ATECC608A; // Tipo di chip cfg.atcai2c.slave_address = 0XC0; // indirizzo I2C (valore predefinito) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Ritardo di risveglio (1500 ms) cfg.rx_retries = 20; radio.begin(); radio.setDataRate(RF24_250KBPS); radio.maskIRQ(1, 1, 0); radio.enableAckPayload(); radio.setRetries(5, 5); radio.openWritingPipe(slaveaddresse); radio.openReadingPipe(1, masteraddresse); } void loop() { bool rslt; // Invia dati rslt = radio.write(&wake_packet, sizeof(wake_packet)); if (rslt) { // Inizia ad ascoltare radio.startListening(); while (radio.available()) { uint8_t risposta[32]; radio.read(&answer, sizeof(answer)); uint8_t node_id[3]; uint8_t cifra[16]; memcpy(node_id, risposta, 3); memcpy(cifra, risposta + 3, 16); if ((int)node_id == ID_NODE) { uint8_t output[16]; ATCA_STATUS status = aes_basic_decrypt(&cfg, cypher, 16, output, AES_KEY); if (status == ATCA_SUCCESS) { Serial.println("Dati decrittografati: "); for (size_t i = 0; i < 16; i++) { Serial.print((char)output); } } } } } else{ Serial.println("Riconoscimento non ricevuto per Wakup Packet"); } // Sleep mode 8 secondi sleepmode(); }
Se hai domande, sono qui per rispondere
Passaggio 4: 4. Vai oltre
Questo esempio è semplice in modo da poter migliorare questo progetto
Miglioramenti:
- L'AES 128 è di base e puoi utilizzare un altro algoritmo di AES come AES CBC per essere più sicuro.
- Cambiare il modulo wireless (il NRF24L01 è limitato da un payload di 23 Byte)
- …
Se vedi miglioramenti da fare, spiegalo nell'area di discussione
Passaggio 5: conclusione
Spero che questo articolo ti sia utile. Scusa se ho sbagliato nel testo, ma l'inglese non è la mia lingua principale e parlo meglio di quanto scrivo.
Grazie per aver letto tutto.
Divertirsi.
Consigliato:
Comunicazione wireless SmartHome: le basi estreme di MQTT: 3 passaggi
Comunicazione wireless SmartHome: le basi estreme di MQTT: Nozioni di base MQTT: ** Farò una serie di automazione domestica, seguirò i passaggi che ho seguito per imparare tutto ciò che ho fatto in futuro. Questo Instructable è la linea di base su come configurare MQTT da utilizzare nei miei futuri Instructables. Tuttavia
Comunicazione wireless LoRa da 3Km a 8Km con dispositivo E32 (sx1278/sx1276) a basso costo per Arduino, Esp8266 o Esp32: 15 passaggi
Comunicazione Wireless LoRa da 3Km a 8Km con dispositivo Low Cost E32 (sx1278/sx1276) per Arduino, Esp8266 o Esp32: creo una libreria per gestire EBYTE E32 basata sulla serie Semtech del dispositivo LoRa, dispositivo molto potente, semplice ed economico. Versione 3Km qui, versione 8Km qui Possono lavorare su una distanza da 3000 m a 8000 m e hanno molte funzioni e
Comunicazione wireless a lungo raggio, 1,8 km, da Arduino ad Arduino con l'HC-12: 6 passaggi (con immagini)
Comunicazione wireless a lungo raggio, 1,8 km, da Arduino ad Arduino con l'HC-12: in questo tutorial imparerai come comunicare tra Arduino su una lunga distanza fino a 1,8 km all'aperto. L'HC-12 è una porta seriale wireless modulo di comunicazione molto utile, estremamente potente e facile da usare. Per prima cosa partirai
Comunicazione wireless utilizzando il modulo ricetrasmettitore NRF24L01 per progetti basati su Arduino: 5 passaggi (con immagini)
Comunicazione wireless utilizzando il modulo ricetrasmettitore NRF24L01 per progetti basati su Arduino: questo è il mio secondo tutorial istruttivo su robot e microcontrollori. È davvero incredibile vedere il tuo robot vivo e funzionare come previsto e credimi sarà più divertente se controlli il tuo robot o altre cose wireless con velocità e
Crea gratuitamente una partizione del disco rigido nascosta e crittografata: 4 passaggi
Crea gratuitamente una partizione del disco rigido nascosta e crittografata: ecco come creare una partizione, come le unità C: o D: che sono già su un nuovo computer, ma è nascosta a tutti (non viene visualizzata sul mio computer o qualcosa del genere) e ha una crittografia di livello governativo, e tutto gratuitamente. Richiederà