Trådløs kryptert kommunikasjon Arduino: 5 trinn
Trådløs kryptert kommunikasjon Arduino: 5 trinn
Anonim
Trådløs kryptert kommunikasjon Arduino
Trådløs kryptert kommunikasjon Arduino

Hei alle sammen, I denne andre artikkelen vil jeg forklare deg hvordan du bruker brikken Atecc608a for å sikre din trådløse kommunikasjon. Til dette vil jeg bruke NRF24L01+ for den trådløse delen og Arduino UNO.

Mikrochippen ATECC608A er designet av MicroChip og har flere sikkerhetsverktøy. For eksempel kan denne brikken lagre ECC Keys, AES Keys (for AES 128) og SHA2 Hash.

Artikkelen: NRF24L01 + Arduino UNO + ATECC608A

Under en kommunikasjon mellom to IoT -objekter kan det eksistere flere angrep: Man Of the mild, kopi av informasjon og mer.. Så ideen min er veldig enkel:

  1. Utnyttelse av krypterte data mellom to eller flere IoT -objekter.
  2. Lavprisrekvisita
  3. Kan jobbe med en Arduino UNO

I mitt tilfelle bruker jeg

  • Atecc608a for å lagre AES -nøkkelen min og for å kryptere/dekryptere dataene mine.
  • Arduino Uno som mikrokontroller
  • NRF24L01 for å sende dataene mine

Du må følge disse trinnene for dette prosjektet:

  1. Sett opp brikken ATECC608A
  2. Gjør kretsen (Master Node og Slave Node)
  3. Kode del
  4. Gå videre !

For de første trinnene "Sett opp brikken ATECC608A", skrev jeg en annen artikkel som forklarer hvert trinn i rekkefølge. Lenken er her:

Start nå!

Rekvisita

For dette prosjektet trenger du:

  • 2 Arduino UNO eller Arduino NANO eller Arduino Mega
  • Noen ledninger
  • 2 Atecc608a (hver kostet mindre enn 0,60 $)
  • 2 NRF24L01+
  • 2 kondensator (10 μF)
  • Brødbrett

Lenke til artikkelen min som forklarer hvordan du konfigurerer brikken ATECC608A -> Hvordan du konfigurerer Atecc608a

Trinn 1: 1. Sett opp Atecc608a

1. Sett opp Atecc608a
1. Sett opp Atecc608a
1. Sett opp Atecc608a
1. Sett opp Atecc608a

Jeg vil ikke beskrive hvert trinn for å sette opp en ATECC608A fordi jeg skrev en full artikkel som forklarer alle trinnene for å gjøre det. For å sette det opp må du følge "Trinn 4" i denne artikkelen kalt "2. Konfigurasjon av brikken (Atecc608a)"

Koblingen er: Hvordan sette opp en ATECC608A

Du må også sette den samme konfigurasjonen for Atecc608a, hovedsiden og slavesiden, ellers kan du ikke dekryptere dataene dine

Advarsel:

For å sette opp denne brikken må du følge alle trinnene i artikkelen ovenfor i rekkefølge. Hvis ett trinn mangler eller brikken ikke er låst, kan du ikke gjøre dette prosjektet

Resten:

Trinn for å følge dette:

  • Lag en konfigurasjonsmal
  • Skriv denne malen til brikken
  • Lås konfigurasjonssonen
  • Skriv din AES -nøkkel (128 bits) i et spor
  • Lås datasonen

Trinn 2: 2. Design av kretsen (Master og Slave)

2. Utforming av kretsen (Master og Slave)
2. Utforming av kretsen (Master og Slave)
2. Utforming av kretsen (Master og Slave)
2. Utforming av kretsen (Master og Slave)

I dette prosjektet vil du ha en Master Node og en Slave Node.

Hovednoden vil skrive ut dataene som sendes av slave -noden i en klar. Den vil be om data fra slavenoden hver X gang.

Slavenoden vil lytte til "nettverket", og når den mottar en "Forespørselsdata", vil den generere den, kryptere den og sende den til hovednoden.

For begge sider, master og slave er kretsen den samme:

  • En arduino Nano
  • En ATECC608A
  • En NRF24L01

Jeg festet kretsen til dette trinnet (jf. Bildet ovenfor).

For ATECC608A til Arduino UNO er dette en soic 8 -pinners. Jeg la til "ovenfra" ovenfor:

  • ARDUINO 3.3V -> PIN 8 (Atecc608a)
  • ARDUINO GND -> PIN 4 (Atecc608a)
  • ARDUINO A4 (SDL) -> PIN 5 (Atecc608a)
  • ARDUINO A5 (SCL) -> PIN 6 (Atecc608a)

For NRF24L01 til 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) -> bare for Slave -node, ikke brukt i Master -modus

Hvorfor bruke IRQ -pinnen til NRF24L01

IRQ -pinnen er veldig nyttig, denne pinnen lar deg si (LOW) når en pakke mottas av NRF24L01, slik at vi kan feste en Interrupt til denne pinnen for å vekke slavenoden.

Trinn 3: 3. Koden (Slave og Master)

3. koden (slave og master)
3. koden (slave og master)

Slave Node

Jeg bruker strømsparing for slave -noden fordi den ikke trenger å lytte hele tiden.

Slik fungerer det: Slave -noden lytter og venter på å motta en "Wake UP -pakke". Denne pakken sendes av hovednoden for å be om data fra slaven.

I mitt tilfelle bruker jeg en rekke med to int:

// Wake UP -pakken

const int wake_packet [2] = {20, 02};

Hvis noden min mottar en pakke,

  1. den våkner, les denne pakken, hvis pakken er en "Wake UP",
  2. det genererer dataene,
  3. kryptere dataene,
  4. send dataene til masteren, vent på en ACK -pakke,
  5. søvn.

For AES -kryptering bruker jeg en nøkkel i sporet nummer 9.

Dette er koden min for Slave -noden

#include "Arduino.h" #include "avr/sleep.h" #include "avr/wdt.h"

#inkludere "SPI.h"

#include "nRF24L01.h" #include "RF24.h"

#inkludere "Wire.h"

// ATECC608A bibliotek

#include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h"

#define ID_NODE 255

#define AES_KEY (uint8_t) 9

ATCAIfaceCfg cfg;

ATCA_STATUS status;

RF24 radio (9, 10);

const uint64_t masteraddresse = 0x1111111111;

const uint64_t slaveaddresse = 0x1111111100;

/**

* / brief Funksjon utført når interrupt er satt (IRQ LOW) * * */ void wakeUpIRQ () {while (radio.available ()) {int data [32]; radio.read (& data, 32); hvis (data [0] == 20 && data [1] == 02) {flytemperatur = 17,6; flyte nynning = 16,4;

uint8_t data [16];

uint8_t cypherdata [16];

// Bygg en streng for å angi all min verdi

// Hver verdi er atskilt med en "|" og "$" betyr slutten på data // ADVARSEL: Må være mindre enn 11 lengde String tmp_str_data = String (ID_NODE) + "|" + String (temp, 1) + "|" + String (hum, 1) + "$"; // størrelse på 11 Serial.println ("tmp_str_data:" + tmp_str_data);

tmp_str_data.getBytes (data, sizeof (data));

// Krypter dataene

ATCA_STATUS status = aes_basic_encrypt (& cfg, data, sizeof (data), cypherdata, AES_KEY); hvis (status == ATCA_SUCCESS) {lang rand = tilfeldig ((lang) 10000, (lang) 99999);

// generer en UUID basert på de tre første tallene = ID -noden

String uuid = String (ID_NODE) + String (rand); // Størrelse på 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)); // Slutt å lytte til radio.stopListening ();

bool rslt;

// Send data rslt = radio.write (& data_to_send, sizeof (data_to_send)); // Begynn å lytte radio.startListening (); if (rslt) {// Slutt- og hvilemodus Serial.println (F ("Ferdig")); }}}}}

ugyldig oppsett ()

{Serial.begin (9600);

// Start konstruktøren for biblioteket

cfg.iface_type = ATCA_I2C_IFACE; // Kommunikasjonstype -> I2C -modus cfg.devtype = ATECC608A; // Type brikke cfg.atcai2c.slave_address = 0XC0; // I2C -adresse (standardverdi) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Forsinkelse av våkne (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); // Fest avbrudd til pinne 3 // Endre 1 med O hvis du vil at avbruddet til pinne 2 // FALLING MODE = Pin ved LOW attachInterrupt (1, wakeUpIRQ, FALLING); }

hulrom ()

{// ikke nødvendig}

Master Node

Hovednoden våkner hvert åttende sekund for å be om data fra slavenoden

Slik fungerer det: Hovednoden sender en "WakeUP" -pakke til slaven og etter å ha ventet et svar fra slaven med data.

I mitt tilfelle bruker jeg en rekke med to int:

// Wake UP -pakken

const int wake_packet [2] = {20, 02};

Hvis slavenoden sender en ACK -pakke etter at masteren har sendt en WakeUp -pakke:

  1. Master satt opp i lyttemodus og vent på en kommunikasjon
  2. Hvis kommunikasjon
  3. Trekk ut den 8 første byten, plyndre den tre første byten av de 8 byte, hvis dette er ID -noden
  4. Trekk ut 16 byte med siffer
  5. Dekrypter dataene
  6. Skriv ut dataene i serie
  7. Sove modus

For AES -kryptering bruker jeg en nøkkel i sporet nummer 9.

Dette er koden min for Master -noden

#inkludere "Arduino.h"

#include "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // ATECC608A library #include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h" #define ID_NODE 255 #define AES_KEY (uint8_t) 9 ATCAIfaceCfg cfg; ATCA_STATUS status; RF24 radio (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Wake UP -pakke const int wake_packet [2] = {20, 02}; // vakthund avbryter ISR (WDT_vect) {wdt_disable (); // deaktiver vaktbikkje} void sleepmode () {// deaktiver ADC ADCSRA = 0; // fjerne forskjellige "reset" -flagg MCUSR = 0; // tillat endringer, deaktiver tilbakestilling WDTCSR = bit (WDCE) | bit (WDE); // sett avbruddsmodus og et intervall WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // sett WDIE, og 8 sekunder forsinkelse wdt_reset (); // tilbakestill vakthunden set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // tidsbestemt sekvens følger sleep_enable (); // slå av brown -out aktivering i programvare MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); avbryter (); // garanterer neste instruksjon utført sleep_cpu (); // avbryt søvn som en forholdsregel sleep_disable (); } ugyldig oppsett () {Serial.begin (9600); // Start konstruktøren for biblioteket cfg.iface_type = ATCA_I2C_IFACE; // Kommunikasjonstype -> I2C -modus cfg.devtype = ATECC608A; // Type brikke cfg.atcai2c.slave_address = 0XC0; // I2C -adresse (standardverdi) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Forsinkelse av våkne (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; // Send data rslt = radio.write (& wake_packet, sizeof (wake_packet)); if (rslt) {// Start Listening radio.startListening (); while (radio.available ()) {uint8_t svar [32]; radio.read (& svar, sizeof (svar)); uint8_t node_id [3]; uint8_t cypher [16]; memcpy (node_id, svar, 3); memcpy (cypher, svar + 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 ("Dekrypterte data:"); for (size_t i = 0; i <16; i ++) {Serial.print ((char) output ); }}}}} else {Serial.println ("Beklager ikke motta for Wakup -pakke"); } // Dvalemodus 8 sekunder sleepmode (); }

Hvis du har spørsmål, er jeg her for å svare

Trinn 4: 4. Gå videre

Dette eksemplet er enkelt, slik at du kan forbedre dette prosjektet

Forbedringer:

  • AES 128 er grunnleggende, og du kan bruke en annen algoritme for AES som AES CBC for å være tryggere.
  • Bytt den trådløse modulen (NRF24L01 er begrenset av en nyttelast på 23 Bytes)

Hvis du ser forbedringer å gjøre, forklar det på diskusjonsområdet

Trinn 5: Konklusjon

Jeg håper denne artikkelen vil være nyttig for deg. Beklager hvis jeg gjorde feil i teksten min, men engelsk er ikke hovedspråket mitt, og jeg snakker bedre enn jeg skriver.

Takk for at du leste alt.

Nyt det.