Innehållsförteckning:

Trådlös krypterad kommunikation Arduino: 5 steg
Trådlös krypterad kommunikation Arduino: 5 steg

Video: Trådlös krypterad kommunikation Arduino: 5 steg

Video: Trådlös krypterad kommunikation Arduino: 5 steg
Video: CS50 2015 – 10-я неделя 2024, November
Anonim
Trådlös krypterad kommunikation Arduino
Trådlös krypterad kommunikation Arduino

Hej alla, I den här andra artikeln kommer jag att förklara dig hur du använder chipet Atecc608a för att säkra din trådlösa kommunikation. För detta kommer jag att använda NRF24L01+ för den trådlösa delen och Arduino UNO.

Mikrochipet ATECC608A har designats av MicroChip och har flera säkerhetsverktyg. Till exempel kan detta chip lagra ECC -nycklar, AES -nycklar (för AES 128) och SHA2 Hash.

Artikeln: NRF24L01 + Arduino UNO + ATECC608A

Under en kommunikation mellan två IoT -objekt kan flera attacker finnas: Man Of the mild, kopia av information och mer.. Så min idé är väldigt enkel:

  1. Användning av krypterad data mellan två eller flera IoT -objekt.
  2. Lågkostnadsmaterial
  3. Kan arbeta med en Arduino UNO

I mitt fall använder jag

  • Atecc608a för att lagra min AES -nyckel och för att kryptera/dekryptera mina data.
  • Arduino Uno som mikrokontroller
  • NRF24L01 för att skicka mina data

Du måste följa dessa steg för detta projekt:

  1. Ställ in chipet ATECC608A
  2. Gör kretsen (Master Node och Slave Node)
  3. Koddel
  4. Gå längre !

För de första stegen "Konfigurera chipet ATECC608A" skrev jag en annan artikel som förklarar varje steg i ordning. Länken är här:

Börja nu!

Tillbehör

För detta projekt behöver du:

  • 2 Arduino UNO eller Arduino NANO eller Arduino Mega
  • Lite tråd
  • 2 Atecc608a (varje kostar mindre än 0,60 $)
  • 2 NRF24L01+
  • 2 kondensator (10 μF)
  • Brödbrädor

Länk till min artikel som förklarar hur du ställer in chipet ATECC608A -> Hur du konfigurerar Atecc608a

Steg 1: 1. Konfigurera Atecc608a

1. Konfigurera Atecc608a
1. Konfigurera Atecc608a
1. Konfigurera Atecc608a
1. Konfigurera Atecc608a

Jag kommer inte att beskriva varje steg för att konfigurera en ATECC608A eftersom jag skrev en fullständig artikel som förklarar alla steg för att göra det. För att konfigurera det måste du följa "Steg 4" i den här artikeln som heter "2. Konfiguration av chipet (Atecc608a)"

Länken är: Så här konfigurerar du en ATECC608A

Du måste också sätta samma konfiguration för Atecc608a, huvudsidan och slavsidan, annars kommer du inte att kunna dekryptera dina data

Varning:

För att konfigurera detta chip måste du följa varje steg i artikeln ovan i ordning. Om ett steg saknas eller om chipet inte är låst skulle du inte kunna göra det här projektet

Återstoden:

Steg att följa för detta:

  • Skapa en konfigurationsmall
  • Skriv den här mallen till chipet
  • Lås Config Zone
  • Skriv din AES -nyckel (128 bitar) i en plats
  • Lås datazonen

Steg 2: 2. Design av kretsen (Master och Slave)

2. Kretsens utformning (Master och Slave)
2. Kretsens utformning (Master och Slave)
2. Kretsens utformning (Master och Slave)
2. Kretsens utformning (Master och Slave)

I detta projekt kommer du att ha en Master Node och en Slave Node.

Huvudnoden kommer att skriva ut data som skickas av slavnoden i tydlig form. Det kommer att begära data från slavnoden varje X gång.

Slavnoden kommer att lyssna på "nätverket" och när den tar emot "Begär data", kommer den att generera den, kryptera den och skicka den till huvudnoden.

För båda sidor, master och slav är kretsen densamma:

  • En arduino Nano
  • En ATECC608A
  • En NRF24L01

Jag kopplade kretsen till detta steg (se bild ovan).

För ATECC608A till Arduino UNO är detta en soic 8 -stift. Jag lade till "ovanifrån" ovan:

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

För NRF24L01 till 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) -> endast för slavnod, används inte i masterläge

Varför använda IRQ -stiftet på NRF24L01

IRQ -stiftet är mycket användbart. Med denna pin kan man säga (LOW) när ett paket tas emot av NRF24L01, så att vi kan fästa ett avbrott i denna pin för att väcka slavnoden.

Steg 3: 3. koden (slav och master)

3. koden (slav och master)
3. koden (slav och master)

Slavnod

Jag använder power save för slavnoden eftersom den inte behöver lyssna hela tiden.

Så fungerar det: slavnoden lyssnar och väntar på att få ett "Wake UP -paket". Detta paket skickas av huvudnoden för att begära data från slaven.

I mitt fall använder jag en array med två int:

// Wake UP -paket

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

Om min nod får ett paket,

  1. det vaknar, läs det här paketet, om paketet är ett "Wake UP",
  2. det genererar data,
  3. kryptera data,
  4. skicka data till mastern, vänta ett ACK -paket,
  5. sömn.

För AES -kryptering använder jag en nyckel i plats nummer 9.

Detta är min kod för slavnoden

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

#inkludera "SPI.h"

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

#inkludera "Wire.h"

// ATECC608A bibliotek

#inkludera "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 Funktion utförs när avbrottet är inställt (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; float hum = 16,4;

uint8_t data [16];

uint8_t cypherdata [16];

// Skapa en sträng för att ställa in allt mitt värde

// Varje värde separeras med ett "|" och "$" betyder slutet på data // VARNING: Måste vara mindre än 11 längd String tmp_str_data = String (ID_NODE) + "|" + Sträng (temp, 1) + "|" + String (hum, 1) + "$"; // storlek på 11 Serial.println ("tmp_str_data:" + tmp_str_data);

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

// Kryptera data

ATCA_STATUS status = aes_basic_encrypt (& cfg, data, sizeof (data), cypherdata, AES_KEY); if (status == ATCA_SUCCESS) {lång rand = slumpmässig ((lång) 10000, (lång) 99999);

// generera ett UUID baserat på de tre första siffrorna = ID -noden

String uuid = String (ID_NODE) + String (rand); // Storlek 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)); // Sluta lyssna på radio.stopListening ();

bool rslt;

// Skicka data rslt = radio.write (& data_to_send, sizeof (data_to_send)); // Börja lyssna radio.startListening (); if (rslt) {// Avsluta och viloläge Serial.println (F ("Klart")); }}}}}

void setup ()

{Serial.begin (9600);

// Starta konstruktören för biblioteket

cfg.iface_type = ATCA_I2C_IFACE; // Typ av kommunikation -> I2C -läge cfg.devtype = ATECC608A; // Typ av chip cfg.atcai2c.slave_address = 0XC0; // I2C -adress (standardvärde) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Fördröjning av väckning (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); // Fäst avbrott på stift 3 // Ändra 1 med O om du vill ha avbrottet till stift 2 // FALLING MODE = Pin vid LOW attachInterrupt (1, wakeUpIRQ, FALLING); }

void loop ()

{ // Behövs inte }

Master Node

Huvudnoden vaknar var 8: e sekund för att be data från slavnoden

Hur det fungerar: Huvudnoden skickar ett "WakeUP" -paket till slaven och efter väntan ett svar från slaven med data.

I mitt fall använder jag en array med två int:

// Wake UP -paket

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

Om slavnoden skickar ett ACK -paket efter att mastern skickat ett WakeUp -paket:

  1. Mästaren ställs in i lyssningsläge och väntar på en kommunikation
  2. Om kommunikation
  3. Extrahera den 8 första byten, plundra de tre första byten av de 8 byten, om detta är ID -noden
  4. Extrahera 16 byte cyper
  5. Dekryptera data
  6. Skriv ut data i serie
  7. Viloläge

För AES -kryptering använder jag en nyckel i plats nummer 9.

Detta är min kod för Master -noden

#inkludera "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 -paket const int wake_packet [2] = {20, 02}; // vakthund avbryter ISR (WDT_vect) {wdt_disable (); // inaktivera vakthund} void sleepmode () {// inaktivera ADC ADCSRA = 0; // rensa olika "reset" -flaggor MCUSR = 0; // tillåt ändringar, inaktivera återställning WDTCSR = bit (WDCE) | bit (WDE); // ställ in avbrottsläge och ett intervall WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // ställ in WDIE och 8 sekunder fördröjning wdt_reset (); // återställ vakthundens set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // tidsinställd sekvens följer sleep_enable (); // Stäng av aktivering av brown -out i programvaran MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); avbryter (); // garanterar nästa instruktion utförd sleep_cpu (); // avbryt sömn som en försiktighetsåtgärd sleep_disable (); } void setup () {Serial.begin (9600); // Starta konstruktören för biblioteket cfg.iface_type = ATCA_I2C_IFACE; // Typ av kommunikation -> I2C -läge cfg.devtype = ATECC608A; // Typ av chip cfg.atcai2c.slave_address = 0XC0; // I2C -adress (standardvärde) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Fördröjning av väckning (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; // Skicka data rslt = radio.write (& wake_packet, sizeof (wake_packet)); if (rslt) {// Börja lyssna radio.startListening (); medan (radio.available ()) {uint8_t svar [32]; radio.read (& svara, sizeof (svar)); uint8_t nod_id [3]; uint8_t cypher [16]; memcpy (nod_id, svar, 3); memcpy (cypher, svara + 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 ("Dekrypterad data:"); för (size_t i = 0; i <16; i ++) {Serial.print ((char) output ); }}}}} else {Serial.println ("Ack får inte för Wakup -paket"); } // Viloläge 8 sekunder sömnläge (); }

Om du har frågor är jag här för att svara

Steg 4: 4. Gå vidare

Detta exempel är enkelt så att du kan förbättra detta projekt

Förbättringar:

  • AES 128 är grundläggande och du kan använda en annan algoritm för AES som AES CBC för att vara säkrare.
  • Byt den trådlösa modulen (NRF24L01 är begränsad av en nyttolast på 23 byte)

Om du ser förbättringar att göra, förklara det på diskussionsområdet

Steg 5: Slutsats

Jag hoppas att den här artikeln kommer att vara användbar för dig. Förlåt om jag gjorde fel i min text men engelska är inte mitt huvudspråk och jag talar bättre än jag skriver.

Tack för att du läste allt.

Njut av det.

Rekommenderad: