Turinys:

Belaidis šifruotas ryšys „Arduino“: 5 žingsniai
Belaidis šifruotas ryšys „Arduino“: 5 žingsniai

Video: Belaidis šifruotas ryšys „Arduino“: 5 žingsniai

Video: Belaidis šifruotas ryšys „Arduino“: 5 žingsniai
Video: Осветите свой мир (с помощью лампочек Hue), Дэн Брэдли 2024, Lapkritis
Anonim
Belaidis šifruotas ryšys „Arduino“
Belaidis šifruotas ryšys „Arduino“

Sveiki visi, Šiame antrame straipsnyje aš jums paaiškinsiu, kaip naudoti „Atecc608a“lustą belaidžiam ryšiui apsaugoti. Tam aš naudosiu NRF24L01+ belaidžio ryšio daliai ir „Arduino UNO“.

„MicroChip“suprojektavo mikro mikroschemą ATECC608A ir gavo kelis saugos įrankius. Pavyzdžiui, šiame luste galima laikyti ECC raktus, AES raktus (AES 128) ir SHA2 maišas.

Straipsnis: NRF24L01 + Arduino UNO + ATECC608A

Bendraujant tarp dviejų daiktų interneto objektų gali būti kelios atakos: žmogus iš lengvos, informacijos kopija ir dar daugiau. Taigi mano idėja labai paprasta:

  1. Šifruotų duomenų naudojimas tarp dviejų ar daugiau IoT objektų.
  2. Pigios prekės
  3. Gali dirbti su „Arduino UNO“

Mano atveju aš naudoju

  • „Atecc608a“mano AES raktui saugoti ir mano duomenims užšifruoti/iššifruoti.
  • „Arduino Uno“kaip mikrovaldiklis
  • NRF24L01 siųsti mano duomenis

Šiame projekte turite atlikti šiuos veiksmus:

  1. Nustatykite lustą ATECC608A
  2. Atlikite grandinę (pagrindinis ir verginis mazgas)
  3. Kodo dalis
  4. Eik toliau!

Pirmiesiems žingsniams „Nustatyti lustą ATECC608A“parašiau kitą straipsnį, kuriame paaiškintas kiekvienas žingsnis. Nuoroda yra čia:

Dabar pradėk!

Prekės

Šiam projektui jums reikia:

  • 2 „Arduino UNO“arba „Arduino NANO“arba „Arduino Mega“
  • Kažkoks laidas
  • 2 „Atecc608a“(kiekvienas kainuoja mažiau nei 0,60 USD)
  • 2 NRF24L01+
  • 2 kondensatorius (10 μF)
  • Duonos lentos

Nuoroda į mano straipsnį, kuriame paaiškinta, kaip nustatyti lustą ATECC608A -> Kaip nustatyti „Atecc608a“

1 veiksmas: 1. Nustatykite „Atecc608a“

1. Nustatykite „Atecc608a“
1. Nustatykite „Atecc608a“
1. Nustatykite „Atecc608a“
1. Nustatykite „Atecc608a“

Nenurodysiu kiekvieno žingsnio, kurį reikia atlikti norint nustatyti ATECC608A, nes parašiau visą straipsnį, kuriame paaiškinami visi žingsniai, kaip tai padaryti. Norėdami jį nustatyti, turite atlikti šio straipsnio 4 veiksmą, pavadintą „2. Lusto konfigūracija (Atecc608a)“

Nuoroda yra tokia: Kaip nustatyti ATECC608A

Be to, turite įdėti tą pačią „Atecc608a“, pagrindinės ir pavaldžiosios pusės konfigūraciją, kitaip negalėsite iššifruoti savo duomenų

Įspėjimas:

Norėdami nustatyti šį lustą, turite atlikti visus aukščiau esančio straipsnio veiksmus. Jei trūksta vieno žingsnio arba lustas nėra užrakintas, negalėsite atlikti šio projekto

Priminimas:

Norėdami tai padaryti, atlikite šiuos veiksmus:

  • Sukurkite konfigūracijos šabloną
  • Įrašykite šį šabloną į lustą
  • Užrakinkite konfigūracijos zoną
  • Įveskite AES raktą (128 bitai) į angą
  • Užrakinkite duomenų zoną

2 žingsnis: 2. Grandinės projektavimas (pagrindinis ir pavaldus)

2. Grandinės dizainas (kapitonas ir vergas)
2. Grandinės dizainas (kapitonas ir vergas)
2. Grandinės dizainas (pagrindinis ir vergas)
2. Grandinės dizainas (pagrindinis ir vergas)

Šiame projekte turėsite pagrindinį mazgą ir vergų mazgą.

Pagrindinis mazgas aiškiai atspausdins vergo mazgo siunčiamus duomenis. Ji paprašys duomenų iš vergo mazgo kas X kartą.

Verginis mazgas įsiklausys į „tinklą“ir, gavęs „užklausos duomenis“, jį sugeneruos, užšifruos ir nusiųs į pagrindinį mazgą.

Abiejose pusėse grandinė ir valdovas yra vienodi:

  • Vienas arduino Nano
  • Vienas ATECC608A
  • Vienas NRF24L01

Prie šio žingsnio prijungiau grandinę (žr. Paveikslėlį aukščiau).

„Arduino UNO“ATECC608A atveju tai yra 8 kaiščių soic. Aš pridėjau „vaizdą iš viršaus“aukščiau:

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

„NRF24L01“į „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) -> tik pavaldžiajam mazgui, nenaudojamas pagrindiniame režime

Kodėl verta naudoti NRF24L01 IRQ kaištį?

IRQ smeigtukas yra labai naudingas, šis kaištis leidžia pasakyti (LOW), kai paketą gauna NRF24L01, todėl prie šio kaiščio galime prijungti pertrauką, kad pažadintume verginį mazgą.

3 žingsnis: 3. Kodas (vergas ir šeimininkas)

3. Kodas (vergas ir šeimininkas)
3. Kodas (vergas ir šeimininkas)

Vergų mazgas

Aš naudoju energijos taupymą vergiui mazgui, nes jam nereikia visą laiką klausytis.

Kaip tai veikia: vergas mazgas klauso ir laukia, kol gaus „Wake UP paketą“. Šį paketą siunčia pagrindinis mazgas, kad paprašytų duomenų iš vergo.

Mano atveju naudoju dviejų int masyvą:

// Pakelti paketą

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

Jei mano mazgas gauna paketą,

  1. atsibunda, perskaitykite šį paketą, jei paketas yra „pabusti“,
  2. jis generuoja duomenis,
  3. užšifruoti duomenis,
  4. nusiųskite duomenis kapitonui, palaukite ACK paketo,
  5. miegoti.

AES šifravimui aš naudoju raktą lizdo numeryje 9.

Tai mano vergo mazgo kodas

#įtraukimas "Arduino.h" #įtraukimas "avr/sleep.h" #įtraukimas "avr/wdt.h"

#įtraukti „SPI.h“

#įtraukti „nRF24L01.h“#įtraukti „RF24.h“

#įtraukti „Wire.h“

// ATECC608A biblioteka

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

#55. ID

#define AES_KEY (uint8_t) 9

ATCAIfaceCfg cfg;

ATCA_STATUS būsena;

Radijas RF24 (9, 10);

const uint64_t masteraddresse = 0x1111111111;

const uint64_t slaveaddresse = 0x1111111100;

/**

* / short Funkcija vykdoma, kai nustatytas pertraukimas (IRQ LOW) * * */ void wakeUpIRQ () {while (radio.available ()) {int data [32]; radio.read (& duomenys, 32); if (duomenys [0] == 20 && duomenys [1] == 02) {plūdės temp = 17,6; plūduriuoti hum = 16,4;

uint8_t duomenys [16];

uint8_t cypherdata [16];

// Sukurkite eilutę, kad nustatytumėte visą mano vertę

// Kiekviena reikšmė yra atskirta "|" ir „$“reiškia duomenų pabaigą // ĮSPĖJIMAS: turi būti trumpesnė nei 11 ilgių eilutė tmp_str_data = Styga (ID_NODE) + "|" + Eilutė (temp, 1) + "|" + Styga (hum, 1) + "$"; // dydis 11 Serial.println ("tmp_str_data:" + tmp_str_data);

tmp_str_data.getBytes (duomenys, dydis (duomenys));

// Šifruoti duomenis

ATCA_STATUS status = aes_basic_encrypt (& cfg, data, sizeof (data), cypherdata, AES_KEY); if (status == ATCA_SUCCESS) {ilgas randas = atsitiktinis ((ilgas) 10000, (ilgas) 99999);

// generuoti UUID pagal tris pirmuosius skaičius = ID mazgas

Eilutė uuid = Styga (ID_NODE) + Eilutė (randas); // Dydis 8

uint8_t tmp_uuid [8];

uint8_t data_to_send [32];

uuid.getBytes (tmp_uuid, sizeof (tmp_uuid) + 1);

memcpy (duomenys_siųsti, tmp_uuid, sizeof (tmp_uuid));

memcpy (data_to_send + sizeof (tmp_uuid), cypherdata, sizeof (cypherdata)); // Nustokite klausytis radijo.stopListening ();

bool rslt;

// Siųsti duomenis rslt = radio.write (& data_to_send, sizeof (data_to_send)); // Pradėti klausytis radijo.startListening (); if (rslt) {// Pabaigos ir miego režimas Serial.println (F ("Atlikta")); }}}}}

negaliojanti sąranka ()

{Serial.begin (9600);

// Iniciatorius bibliotekai

cfg.iface_type = ATCA_I2C_IFACE; // Ryšio tipas -> I2C režimas cfg.devtype = ATECC608A; // Lusto tipas cfg.atcai2c.slave_address = 0XC0; // I2C adresas (numatytoji vertė) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Pažadinimo vėlavimas (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); // Prijunkite pertrauką prie kaiščio 3 // Modifikuokite 1 O, jei norite pertraukti 2 kaištį // FALLING MODE = Pin at LOW attachInterrupt (1, wakeUpIRQ, FALLING); }

tuštumos kilpa ()

{ // Nereikia }

Pagrindinis mazgas

Pagrindinis mazgas atsibunda kas 8 sekundes prašyti duomenų iš vergo mazgo

Kaip tai veikia: pagrindinis mazgas siunčia „WakeUP“paketą vergui ir palaukęs atsako į atsakymą su duomenimis.

Mano atveju naudoju dviejų int masyvą:

// Pakelti paketą

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

Jei pagalbinis mazgas siunčia ACK paketą po to, kai kapitonas atsiuntė „WakeUp“paketą:

  1. Meistras nustatė klausymo režimu ir palaukite ryšio
  2. Jei bendravimas
  3. Ištraukite 8 pirmąjį baitą, išplėškite tris pirmuosius 8 baitus, jei tai yra ID mazgas
  4. Ištraukite 16 baitų šifro
  5. Iššifruoti duomenis
  6. Spausdinkite duomenis serijiniu būdu
  7. Miegojimo rezimas

AES šifravimui aš naudoju raktą 9 lizdo numeryje.

Tai mano pagrindinis mazgo kodas

#įtraukti „Arduino.h“

#include "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // ATECC608A biblioteka #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 būsena; Radijas RF24 (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Wake UP paketas const int wake_packet [2] = {20, 02}; // budėtojo pertraukimo ISR (WDT_vect) {wdt_disable (); // disable watchdog} void sleepmode () {// išjungti ADC ADCSRA = 0; // išvalyti įvairias „reset“vėliavas MCUSR = 0; // leisti pakeitimus, išjungti atstatymą WDTCSR = bit (WDCE) | bitai (WDE); // nustatyti pertraukimo režimą ir intervalą WDTCSR = bit (WDIE) | bitai (WDP3) | bitų (WDP0); // nustatyti WDIE, ir 8 sekundės delsos wdt_reset (); // atstatyti sargybinį set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // laiko seka seka sleep_enable (); // programinėje įrangoje išjunkite „Brown -out“įgalinimą MCUCR = bit (BODS) | bitas (BODSE); MCUCR = bit (BODS); pertraukia (); // garantuoja kitą vykdomą instrukciją sleep_cpu (); // atšaukti miegą kaip atsargumo priemonę sleep_disable (); } void setup () {Serial.begin (9600); // Pradėkite bibliotekos kūrėją cfg.iface_type = ATCA_I2C_IFACE; // Ryšio tipas -> I2C režimas cfg.devtype = ATECC608A; // Lusto tipas cfg.atcai2c.slave_address = 0XC0; // I2C adresas (numatytoji vertė) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Pažadinimo vėlavimas (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; // Siųsti duomenis rslt = radio.write (& wake_packet, sizeof (wake_packet)); if (rslt) {// Pradėti klausytis radijo.startListening (); while (radio.available ()) {uint8_t atsakymas [32]; radio.read (& atsakymas, dydis (atsakymas)); uint8_t node_id [3]; uint8_t cypher [16]; memcpy (mazgo ID, atsakymas, 3); memcpy (šifras, atsakymas + 3, 16); if ((int) node_id == ID_NODE) {uint8_t output [16]; ATCA_STATUS statusas = aes_basic_decrypt (& cfg, cypher, 16, output, AES_KEY); if (status == ATCA_SUCCESS) {Serial.println ("Iššifruoti duomenys:"); for (size_t i = 0; i <16; i ++) {Serial.print ((char) išvestis ); }}}}} else {Serial.println ("Ack not get for Wakup Packet"); } // Miego režimas 8 sekundžių miego režimas (); }

Jei turite klausimų, aš čia atsakysiu

4 žingsnis: 4. Eikite toliau

Šis pavyzdys yra paprastas, todėl galite patobulinti šį projektą

Patobulinimai:

  • AES 128 yra pagrindinis ir jūs galite naudoti kitą AES algoritmą kaip AES CBC, kad būtumėte saugesni.
  • Pakeiskite belaidį modulį (NRF24L01 riboja 23 baitų naudingoji apkrova)

Jei matote, ką reikia padaryti, paaiškinkite tai diskusijų srityje

5 žingsnis: Išvada

Tikiuosi, kad šis straipsnis jums bus naudingas. Atsiprašau, jei suklydau tekste, bet anglų kalba nėra mano pagrindinė kalba ir aš kalbu geriau nei rašau.

Ačiū, kad viską perskaitėte.

Mėgaukis tuo.

Rekomenduojamas: