Cuprins:

Comunicare criptată fără fir Arduino: 5 pași
Comunicare criptată fără fir Arduino: 5 pași
Anonim
Comunicare wireless criptată Arduino
Comunicare wireless criptată Arduino

Bună ziua tuturor, În acest al doilea articol, vă voi explica cum să utilizați cipul Atecc608a pentru a vă asigura comunicația fără fir. Pentru aceasta, voi folosi NRF24L01 + pentru partea Wireless și Arduino UNO.

Microcipul ATECC608A a fost proiectat de MicroChip și are mai multe instrumente de securitate. De exemplu, acest cip poate stoca chei ECC, chei AES (pentru AES 128) și SHA2 Hash.

Articolul: NRF24L01 + Arduino UNO + ATECC608A

În timpul unei comunicări între două obiecte IoT, pot exista atacuri multiple: Omul celor blânzi, Copie de informații și multe altele.. Deci ideea mea este foarte simplă:

  1. Utilizarea datelor criptate între două sau mai multe obiecte IoT.
  2. Aprovizionare cu cost redus
  3. Poate funcționa cu un Arduino UNO

În cazul meu, folosesc

  • Atecc608a pentru a stoca cheia mea AES și pentru a cripta / decripta datele mele.
  • Arduino Uno ca microcontroler
  • NRF24L01 pentru a-mi trimite datele

Trebuie să urmați acești pași pentru acest proiect:

  1. Configurați cipul ATECC608A
  2. Faceți circuitul (nodul principal și nodul sclav)
  3. Cod parte
  4. Mergi mai departe !

Pentru primii pași „Configurarea cipului ATECC608A”, am scris un alt articol care explică fiecare pas în ordine. Link-ul este aici:

Acum începe!

Provizii

Pentru acest proiect aveți nevoie de:

  • 2 Arduino UNO sau Arduino NANO sau Arduino Mega
  • Niște sârmă
  • 2 Atecc608a (fiecare costă mai puțin de 0,60 $)
  • 2 NRF24L01 +
  • 2 condensatori (10 μF)
  • Panouri

Link către articolul meu care explică modul de configurare a cipului ATECC608A -> Cum se configurează Atecc608a

Pasul 1: 1. Configurați Atecc608a

1. Configurați Atecc608a
1. Configurați Atecc608a
1. Configurați Atecc608a
1. Configurați Atecc608a

Nu voi detalia fiecare pas de urmat pentru a configura un ATECC608A, deoarece am scris un articol complet care explică fiecare etapă pentru a o face. Pentru a-l configura, trebuie să urmați „Pasul 4” din acest articol numit „2. Configurarea cipului (Atecc608a)”

Link-ul este: Cum se configurează un ATECC608A

De asemenea, trebuie să puneți aceeași configurație pentru Atecc608a, partea master și partea slave, altfel nu veți putea decripta datele

Avertizare:

Pentru a configura acest cip, trebuie să urmați toți pașii articolului de mai sus în ordine. Dacă lipsește un pas sau cipul nu este blocat, nu ați putea face acest proiect

Rest:

Pasul de urmat pentru aceasta:

  • Creați un șablon de configurare
  • Scrieți acest șablon pe cip
  • Blocați zona de configurare
  • Scrieți cheia AES (128 biți) într-un slot
  • Blocați zona de date

Pasul 2: 2. Proiectarea circuitului (Master și Slave)

2. Proiectarea circuitului (Master și Slave)
2. Proiectarea circuitului (Master și Slave)
2. Proiectarea circuitului (Master și Slave)
2. Proiectarea circuitului (Master și Slave)

În acest proiect, veți avea un nod principal și un nod sclav.

Nodul master va imprima datele trimise de nodul slave în clar. Va solicita date de la nodul slave de fiecare dată.

Nodul sclav va asculta „rețeaua” și atunci când va primi un „Solicită date”, îl va genera, cripta și îl va trimite la nodul principal.

Pentru ambele părți, master și slave circuitul este același:

  • Un arduino Nano
  • Unul ATECC608A
  • Unul NRF24L01

Am atașat circuitul la acest pas (cf imaginea de mai sus).

Pentru ATECC608A către Arduino UNO, acesta este un soic 8 pini. Am adăugat „vizualizarea de sus” de mai sus:

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

Pentru NRF24L01 către 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) -> numai pentru nodul Slave, neutilizat în modul Master

De ce să folosiți pinul IRQ al NRF24L01

Pinul IRQ este foarte util, acest pin permite să spună (LOW) când un pachet este primit de către NRF24L01, deci putem atașa o întrerupere la acest pin pentru a trezi nodul sclav.

Pasul 3: 3. Codul (Sclav și Maestru)

3. Codul (Sclav și Maestru)
3. Codul (Sclav și Maestru)

Nodul sclav

Folosesc economisirea energiei pentru nodul sclav, deoarece nu are nevoie să asculte tot timpul.

Cum funcționează: nodul sclav ascultă și așteaptă să primească un „pachet Wake UP”. Acest pachet este trimis de nodul Master pentru a cere date de la sclav.

În cazul meu, folosesc o serie de două int:

// Pachet Wake UP

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

Dacă nodul meu primește un pachet,

  1. se trezește, citește acest pachet, dacă pachetul este un „Trezire”,
  2. generează date,
  3. criptează datele,
  4. trimite datele către master, așteaptă un pachet ACK,
  5. dormi.

Pentru criptarea AES, folosesc o cheie în slotul numărul 9.

Acesta este codul meu pentru nodul Slave

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

#includeți „SPI.h”

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

#include „Wire.h”

// Biblioteca ATECC608A

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

#define ID_NODE 255

#define AES_KEY (uint8_t) 9

ATCAIfaceCfg cfg;

Statutul ATCA_STATUS;

Radio RF24 (9, 10);

const uint64_t masteraddresse = 0x1111111111;

const uint64_t slaveaddresse = 0x1111111100;

/**

* / scurt Funcție executată când este setată întreruperea (IRQ LOW) * * * / void wakeUpIRQ () {while (radio.available ()) {int data [32]; radio.read (& data, 32); if (date [0] == 20 && data [1] == 02) {float temp = 17.6; zumzet plutitor = 16,4;

date uint8_t [16];

uint8_t cypherdata [16];

// Construiește un șir pentru a-mi seta toată valoarea

// Fiecare valoare este separată printr-un „|” iar „$” înseamnă sfârșitul datelor // AVERTISMENT: Trebuie să aibă o lungime mai mică de 11 Șir tmp_str_data = Șir (ID_NODE) + „|” + Șir (temp, 1) + "|" + Șir (zumzet, 1) + "$"; // dimensiunea de 11 Serial.println ("tmp_str_data:" + tmp_str_data);

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

// Criptează datele

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ți un UUID pe baza primului trei număr = nod ID

String uuid = String (ID_NODE) + String (rand); // Dimensiunea de 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)); // Nu mai asculta radio.stopListening ();

bool rslt;

// Trimite date rslt = radio.write (& data_to_send, sizeof (data_to_send)); // Începeți să ascultați radio.startListening (); if (rslt) {// Mod sfârșit și repaus Serial.println (F ("Terminat")); }}}}}

configurare nulă ()

{Serial.begin (9600);

// Inițiați constructorul pentru bibliotecă

cfg.iface_type = ATCA_I2C_IFACE; // Tipul comunicării -> Mod I2C cfg.devtype = ATECC608A; // Tipul cipului cfg.atcai2c.slave_address = 0XC0; // adresă I2C (valoare implicită) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Întârziere trezire (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); // Atașați întreruperea la pinul 3 // Modificați 1 cu O dacă doriți întreruperea la pinul 2 // FALLING MODE = Pin la LOW attachInterrupt (1, wakeUpIRQ, FALLING); }

bucla nulă ()

{ // Nu este nevoie }

Nod Maestru

Nodul master se trezește la fiecare 8 secunde pentru a cere date de la Nodul slave

Cum funcționează: nodul master trimite un pachet „WakeUP” către sclav și după ce așteptați un răspuns al sclavului cu date.

În cazul meu, folosesc o serie de două int:

// Pachet Wake UP

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

Dacă nodul slave trimite un pachet ACK după ce maestrul a trimis un pachet WakeUp:

  1. Master configurat în modul Ascultare și așteptați o comunicare
  2. Dacă comunicarea
  3. Extrageți primul 8 octet, predați primul trei octet al celor 8 octeți, dacă acesta este nodul ID
  4. Extrageți cei 16 octeți de cifru
  5. Decriptați datele
  6. Imprimați datele în serie
  7. Modul de somn

Pentru criptarea AES, folosesc o cheie în slotul numărul 9.

Acesta este codul meu pentru nodul Master

#include „Arduino.h”

#include "avr / sleep.h" #include "avr / wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // Biblioteca ATECC608A #include "ATECCX08A_Arduino / cryptoauthlib.h" #include "AES BASIC / aes_basic.h" #define ID_NODE 255 #define AES_KEY (uint8_t) 9 ATCAIfaceCfg cfg; Statutul ATCA_STATUS; Radio RF24 (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Pachet Wake UP const int wake_packet [2] = {20, 02}; // întrerupere ISR (WDT_vect) {wdt_disable () // disable watchdog} void sleepmode () {// disable ADC ADCSRA = 0; // ștergeți diferite steaguri „resetare” MCUSR = 0; // permite modificări, dezactivează resetarea WDTCSR = bit (WDCE) | bit (WDE); // setați modul de întrerupere și un interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE și 8 secunde întârziere wdt_reset (); // resetați watchdog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // secvența temporizată urmează sleep_enable (); // dezactivați activarea brown-out în software-ul MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); întrerupe (); // garantează următoarea instrucțiune executată sleep_cpu (); // anulați somnul ca măsură de precauție sleep_disable (); } void setup () {Serial.begin (9600); // Inițiați constructorul pentru biblioteca cfg.iface_type = ATCA_I2C_IFACE; // Tipul comunicării -> Mod I2C cfg.devtype = ATECC608A; // Tipul cipului cfg.atcai2c.slave_address = 0XC0; // adresă I2C (valoare implicită) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Întârziere trezire (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; // Trimite date rslt = radio.write (& wake_packet, sizeof (wake_packet)); if (rslt) {// Start Listening radio.startListening (); while (radio.available ()) {uint8_t răspuns [32]; radio.read (& answer, sizeof (answer)); uint8_t node_id [3]; uint8_t cypher [16]; memcpy (node_id, answer, 3); memcpy (cifru, răspuns + 3, 16); if ((int) node_id == ID_NODE) {ieșire uint8_t [16]; ATCA_STATUS status = aes_basic_decrypt (& cfg, cypher, 16, output, AES_KEY); if (status == ATCA_SUCCESS) {Serial.println ("Date decriptate:"); for (size_t i = 0; i <16; i ++) {Serial.print ((char) output ); }}}}} else {Serial.println ("Ack nu primește pentru pachetul Wakup"); } // Mod de repaus 8 secunde sleepmode (); }

Dacă aveți întrebări, sunt aici pentru a răspunde

Pasul 4: 4. Mergeți mai departe

Acest exemplu este simplu, astfel încât să puteți îmbunătăți acest proiect

Îmbunătățiri:

  • AES 128 este de bază și puteți utiliza un alt algoritm al AES ca AES CBC pentru a fi mai sigur.
  • Schimbați modulul wireless (NRF24L01 este limitat de o sarcină utilă de 23 de octeți)

Dacă vedeți o îmbunătățire, explicați-o în zona de discuții

Pasul 5: Concluzie

Sper că acest articol vă va fi de folos. Îmi pare rău dacă am greșit în textul meu, dar engleza nu este limba mea principală și vorbesc mai bine decât scriu.

Mulțumesc că ai citit totul.

Bucură de ea.

Recomandat: