Inhoudsopgave:

Draadloze gecodeerde communicatie Arduino - Ajarnpa
Draadloze gecodeerde communicatie Arduino - Ajarnpa

Video: Draadloze gecodeerde communicatie Arduino - Ajarnpa

Video: Draadloze gecodeerde communicatie Arduino - Ajarnpa
Video: CS50 Live, серия 003 2024, November
Anonim
Draadloze gecodeerde communicatie Arduino
Draadloze gecodeerde communicatie Arduino

Dag iedereen, In dit tweede artikel leg ik je uit hoe je de chip Atecc608a gebruikt om je draadloze communicatie te beveiligen. Hiervoor gebruik ik de NRF24L01+ voor het draadloze gedeelte en de Arduino UNO.

De microchip ATECC608A is ontworpen door MicroChip en heeft meerdere beveiligingstools. Deze chip kan bijvoorbeeld ECC Keys, AES Keys (voor AES 128) en SHA2 Hash opslaan.

Het artikel: NRF24L01 + Arduino UNO + ATECC608A

Tijdens een communicatie tussen twee IoT-objecten kunnen meerdere aanvallen plaatsvinden: Man Of the mild, Copy of information and more.. Dus mijn idee is heel eenvoudig:

  1. Gebruik van versleutelde gegevens tussen twee of meer IoT-objecten.
  2. Goedkope benodigdheden
  3. Kan werken met een Arduino UNO

In mijn geval gebruik ik

  • de Atecc608a om mijn AES-sleutel op te slaan en om mijn gegevens te coderen/decoderen.
  • de Arduino Uno als Microcontroller
  • De NRF24L01 om mijn gegevens te verzenden

U moet deze stappen volgen voor dit project:

  1. Stel de chip ATECC608A in:
  2. Doe het circuit (Master Node en Slave Node)
  3. Code onderdeel
  4. Ga verder !

Voor de eerste stappen "De chip ATECC608A instellen", schreef ik een ander artikel waarin elke stap in volgorde wordt uitgelegd. De link is hier:

Nu beginnen!

Benodigdheden

Voor dit project heb je nodig:

  • 2 Arduino UNO of Arduino NANO of Arduino Mega
  • wat draad
  • 2 Atecc608a (elk kost minder dan $ 0,60)
  • 2 NRF24L01+
  • 2 condensator (10 F)
  • Breadboards

Link naar mijn artikel waarin wordt uitgelegd hoe de chip ATECC608A wordt ingesteld -> Hoe Atecc608a wordt ingesteld

Stap 1: 1. Stel de Atecc608a in

1. Stel de Atecc608a in
1. Stel de Atecc608a in
1. Stel de Atecc608a in
1. Stel de Atecc608a in

Ik zal niet elke stap beschrijven die moet worden gevolgd om een ATECC608A in te stellen, omdat ik een volledig artikel heb geschreven waarin alle stappen worden uitgelegd om dit te doen. Om het in te stellen, moet u de "Stap 4" van dit artikel genaamd " 2. Configuratie van de chip (Atecc608a) " volgen

De link is: Hoe een ATECC608A in te stellen

U moet ook dezelfde configuratie plaatsen voor de Atecc608a, master- en slave-zijde, anders kunt u uw gegevens niet ontsleutelen

Waarschuwing:

Om deze chip in te stellen, moet u alle stappen van het bovenstaande artikel op volgorde volgen. Als een stap ontbreekt of de chip niet vergrendeld is, zou je dit project niet kunnen doen

Rest:

Stap hiervoor te volgen:

  • Een configuratiesjabloon maken
  • Schrijf dit sjabloon naar de chip
  • De configuratiezone vergrendelen
  • Schrijf uw AES-sleutel (128 bits) in een sleuf
  • De gegevenszone vergrendelen

Stap 2: 2. Ontwerp van het circuit (master en slave)

2. Ontwerp van het circuit (master en slave)
2. Ontwerp van het circuit (master en slave)
2. Ontwerp van het circuit (master en slave)
2. Ontwerp van het circuit (master en slave)

In dit project heb je een Master Node en een Slave Node.

Het masterknooppunt zal de gegevens die door het slaveknooppunt zijn verzonden, duidelijk afdrukken. Het zal elke X keer gegevens van de slave-node opvragen.

Het slaveknooppunt luistert naar het "netwerk" en wanneer het een "Request data" ontvangt, zal het deze genereren, versleutelen en naar het masterknooppunt sturen.

Voor beide zijden, master en slave is het circuit hetzelfde:

  • Een Arduino Nano
  • Een ATECC608A
  • Een NRF24L01

Ik heb het circuit aan deze stap bevestigd (zie afbeelding hierboven).

Voor de ATECC608A tot de Arduino UNO is dit een soic 8 pin. Ik heb het "bovenaanzicht" hierboven toegevoegd:

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

Voor de NRF24L01 naar de 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) -> alleen voor Slave-knooppunt, niet gebruikt in Master-modus

Waarom de IRQ-pin van de NRF24L01 gebruiken?

De IRQ-pin is erg handig, deze pin maakt het mogelijk om (LOW) te zeggen wanneer een pakket wordt ontvangen door de NRF24L01, dus we kunnen een Interrupt aan deze pin koppelen om de slave-node te wekken.

Stap 3: 3. de Code (Slaaf en Master)

3. de code (slaaf en meester)
3. de code (slaaf en meester)

Slavenknooppunt

Ik gebruik power save voor de slave Node omdat deze niet altijd hoeft te luisteren.

Hoe het werkt: het slave-knooppunt luistert en wacht op het ontvangen van een "Wake UP-pakket". Dit pakket wordt door de Master-node verzonden om gegevens van de slave op te vragen.

In mijn geval gebruik ik een array van twee int:

// Wake UP-pakket

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

Als mijn node een pakket ontvangt,

  1. het wordt wakker, lees dit pakket, als het pakket een "Wake UP" is,
  2. het genereert de gegevens,
  3. versleutel de gegevens,
  4. stuur de gegevens naar de master, wacht op een ACK-pakket,
  5. slaap.

Voor de AES Encryptie gebruik ik een sleutel in slot nummer 9.

Dit is mijn code voor het Slave-knooppunt

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

#include "SPI.h"

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

#include "Wire.h"

// ATECC608A bibliotheek

#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 = 0x111111111;

const uint64_t slaveaddresse = 0x1111111100;

/**

* \brief Functie uitgevoerd wanneer de interrupt is ingesteld (IRQ LOW) * * */ void wakeUpIRQ() { while (radio.available()) { int data[32]; radio.lezen(&data, 32); if (data[0] == 20 && data[1] == 02) { float temp = 17.6; float brom = 16,4;

uint8_t gegevens[16];

uint8_t cypherdata[16];

// Bouw een string om al mijn waarde in te stellen

// Elke waarde wordt gescheiden door een "|" en de "$" betekent het einde van de gegevens // WAARSCHUWING: moet een lengte hebben van minder dan 11 String tmp_str_data = String(ID_NODE) + "|" + Tekenreeks(temp, 1) + "|" + String (zoem, 1) + "$"; // grootte van 11 Serial.println ("tmp_str_data: " + tmp_str_data);

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

// Versleutel de gegevens

ATCA_STATUS-status = aes_basic_encrypt(&cfg, data, sizeof(data), cypherdata, AES_KEY); if (status == ATCA_SUCCESS) { lange rand = willekeurig ((long)10000, (long)99999);

// genereer een UUID op basis van de eerste drie nummers = ID-knooppunt

String uuid = String (ID_NODE) + String (rand); // Grootte van 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)); // Stop met luisteren naar radio.stopListening();

bool rslt;

// Gegevens verzenden rslt = radio.write(&data_to_send, sizeof(data_to_send)); // Begin met luisteren radio.startListening(); if (rslt) { // Einde en slaapmodus Serial.println (F ("Gereed")); } } } } }

ongeldige setup()

{ Serieel.begin (9600);

// Init de constructor voor de bibliotheek

cfg.iface_type = ATCA_I2C_IFACE; // Type communicatie -> I2C-modus cfg.devtype = ATECC608A; // Type chip cfg.atcai2c.slave_address = 0XC0; // I2C-adres (standaardwaarde) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Vertraging van wekken (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(hoofdadres);

radio.openReadingPipe(1, slaveadres); // Voeg interrupt toe aan pin 3 // Pas 1 aan met O als je de interrupt aan pin 2 wilt // FALLING MODE = Pin op LAAG attachInterrupt(1, wakeUpIRQ, FALLING); }

lege lus()

{ // Niet nodig }

Hoofdknooppunt

Het masterknooppunt wordt elke 8 seconden wakker om gegevens van het slaveknooppunt te vragen

Hoe het werkt: De master node stuurt een "WakeUP" pakket naar de slave en wacht daarna een antwoord van de slave met data.

In mijn geval gebruik ik een array van twee int:

// Wake UP-pakket

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

Als het slave-knooppunt een ACK-pakket verzendt nadat de master een WakeUp-pakket heeft verzonden:

  1. Master instellen in luistermodus en wachten op communicatie
  2. Als communicatie
  3. Pak de eerste 8 byte uit, plunder de eerste drie byte van de 8 bytes, als dit het ID-knooppunt is
  4. Extraheer de 16 byte van cypher
  5. Ontsleutel de gegevens
  6. Druk de gegevens af in Serieel
  7. Slaapstand

Voor de AES Encryptie gebruik ik een sleutel in slot nummer 9.

Dit is mijn code voor het hoofdknooppunt

#include "Arduino.h"

#include "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // ATECC608A-bibliotheek #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 = 0x111111111; const uint64_t slaveaddresse = 0x1111111100; // Wake UP-pakket const int wake_packet [2] = {20, 02}; // watchdog interrupt ISR (WDT_vect) { wdt_disable (); // schakel watchdog uit} void sleepmode () {// schakel ADC ADCSRA uit = 0; // wis verschillende "reset" -vlaggen MCUSR = 0; // wijzigingen toestaan, reset uitschakelen WDTCSR = bit (WDCE) | beetje (WDE); // stel de interrupt-modus en een interval in WDTCSR = bit (WDIE) | bit(WDP3) | beetje (WDP0); // stel WDIE in en 8 seconden vertraging wdt_reset(); // reset de watchdog set_sleep_mode (SLEEP_MODE_PWR_DOWN); geen onderbrekingen(); // getimede reeks volgt sleep_enable (); // schakel brown-out inschakelen in software uit MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit(BODS); onderbreekt(); // garandeert volgende instructie uitgevoerd sleep_cpu(); // annuleer slaap uit voorzorg sleep_disable(); } void setup() { Serial.begin(9600); // Init de constuctor voor de bibliotheek cfg.iface_type = ATCA_I2C_IFACE; // Type communicatie -> I2C-modus cfg.devtype = ATECC608A; // Type chip cfg.atcai2c.slave_address = 0XC0; // I2C-adres (standaardwaarde) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Vertraging van wekken (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(slaveadres); radio.openReadingPipe(1, hoofdadres); } void loop() { bool rslt; // Gegevens verzenden rslt = radio.write(&wake_packet, sizeof(wake_packet)); if (rslt) { // Begin met luisteren radio.startListening(); while (radio.available()) { uint8_t antwoord[32]; radio.read(&answer, sizeof(answer)); uint8_t node_id[3]; uint8_t encryptie[16]; memcpy(node_id, antwoord, 3); memcpy(cypher, antwoord + 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 ("Gedecodeerde gegevens: "); for (size_t i = 0; i <16; i++) {Serial.print((char)output); } } } } } else{ Serial.println ("Bevestig niet ontvangen voor Wakup Packet"); } // Slaapstand 8 seconden slaapstand(); }

Als je een vraag hebt, ben ik hier om deze te beantwoorden

Stap 4: 4. Ga verder

Dit voorbeeld is eenvoudig, zodat u dit project kunt verbeteren

Verbeteringen:

  • De AES 128 is eenvoudig en u kunt een ander algoritme van AES als AES CBC gebruiken om veiliger te zijn.
  • Wijzig de draadloze module (de NRF24L01 is beperkt tot een laadvermogen van 23 bytes)

Als je verbetering ziet, leg het dan uit in het discussiegebied

Stap 5: Conclusie

Ik hoop dat dit artikel nuttig voor u zal zijn. Sorry als ik een fout heb gemaakt in mijn tekst, maar Engels is niet mijn hoofdtaal en ik spreek beter dan ik schrijf.

Bedankt voor het lezen van alles.

Geniet ervan.

Aanbevolen: