Taula de continguts:

Comunicació xifrada sense fils Arduino: 5 passos
Comunicació xifrada sense fils Arduino: 5 passos

Vídeo: Comunicació xifrada sense fils Arduino: 5 passos

Vídeo: Comunicació xifrada sense fils Arduino: 5 passos
Vídeo: BigTreeTech - SKR 3 - TMC2130 with Sensorless Homing 2024, De novembre
Anonim
Comunicació xifrada sense fils Arduino
Comunicació xifrada sense fils Arduino

Hola a tothom, En aquest segon article, us explicaré com utilitzar el xip Atecc608a per protegir la vostra comunicació sense fils. Per a això, utilitzaré el NRF24L01 + per a la part sense fils i l’Arduino UNO.

El micro xip ATECC608A ha estat dissenyat per MicroChip i disposa de múltiples eines de seguretat. Per exemple, aquest xip pot emmagatzemar claus ECC, claus AES (per a AES 128) i SHA2 Hash.

L’article: NRF24L01 + Arduino UNO + ATECC608A

Durant una comunicació entre dos objectes IoT, es poden existir diversos atacs: Home dels dolços, còpia d'informació i molt més. Per tant, la meva idea és molt senzilla:

  1. Utilització de dades xifrades entre dos o més objectes IoT.
  2. Subministraments de baix cost
  3. Pot treballar amb un Arduino UNO

En el meu cas, faig servir

  • l'Atecc608a per emmagatzemar la meva clau AES i xifrar / desxifrar les meves dades.
  • l'Arduino Uno com a microcontrolador
  • El NRF24L01 per enviar les meves dades

Heu de seguir aquests passos per a aquest projecte:

  1. Configureu el xip ATECC608A
  2. Fer el circuit (node mestre i node esclau)
  3. Part del codi
  4. Anar més lluny !

Per als primers passos "Configuració del xip ATECC608A", vaig escriure un altre article que explicava cada pas per ordre. L’enllaç és aquí:

Ara comença!

Subministraments

Per a aquest projecte necessiteu:

  • 2 Arduino UNO o Arduino NANO o Arduino Mega
  • Una mica de filferro
  • 2 Atecc608a (cadascun costa menys de 0,60 $)
  • 2 NRF24L01 +
  • 2 condensadors (10 μF)
  • Taules de pa

Enllaç al meu article que explica com configurar el xip ATECC608A -> Com configurar Atecc608a

Pas 1: 1. Configureu l'Atecc608a

1. Configureu l'Atecc608a
1. Configureu l'Atecc608a
1. Configureu l'Atecc608a
1. Configureu l'Atecc608a

No detallaré tots els passos a seguir per configurar un ATECC608A perquè vaig escriure un article complet que explica tots els passos per fer-ho. Per configurar-lo, heu de seguir el "Pas 4" d'aquest article anomenat "2. Configuració del xip (Atecc608a)"

L’enllaç és: Com configurar un ATECC608A

A més, haureu de posar la mateixa configuració per a l'Atecc608a, el costat mestre i el costat esclau, en cas contrari no podreu desxifrar les vostres dades

Advertència:

Per configurar aquest xip, heu de seguir tots els passos de l'article anterior per ordenar-los. Si falta un pas o el xip no està bloquejat, no podríeu fer aquest projecte

Resta:

Pas a seguir per a això:

  • Creeu una plantilla de configuració
  • Escriviu aquesta plantilla al xip
  • Bloqueja la zona de configuració
  • Escriviu la vostra clau AES (128 bits) en una ranura
  • Bloqueja la zona de dades

Pas 2: 2. Disseny del circuit (mestre i esclau)

2. Disseny del circuit (mestre i esclau)
2. Disseny del circuit (mestre i esclau)
2. Disseny del circuit (mestre i esclau)
2. Disseny del circuit (mestre i esclau)

En aquest projecte, tindreu un node mestre i un node esclau.

El node mestre imprimirà les dades enviades pel node esclau en clar. Sol·licitarà dades del node esclau cada X vegada.

El node esclau escoltarà la "xarxa" i, quan rebi una "Sol·licitud de dades", la generarà, xifrarà i l'enviarà al node mestre.

Per als dos costats, mestre i esclau, el circuit és el mateix:

  • Un arduino Nano
  • Un ATECC608A
  • Un NRF24L01

He adjuntat el circuit a aquest pas (vegeu la imatge superior).

Per a l'ATECC608A a Arduino UNO, es tracta d'un soic de 8 pins. He afegit la "vista superior" anterior:

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

Per al NRF24L01 a l'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) -> només per a node esclau, no usat en mode mestre

Per què utilitzar el pin IRQ del NRF24L01?

El pin IRQ és molt útil, aquest pin permet dir (BAIX) quan el paquet NRF24L01 rep un paquet, de manera que podem connectar una interrupció a aquest pin per despertar el node esclau.

Pas 3: 3. el codi (esclau i mestre)

3. el Codi (Esclau i Mestre)
3. el Codi (Esclau i Mestre)

Node esclau

Faig servir l’estalvi d’energia per al node esclau perquè no necessita escoltar-ho tot el temps.

Com funciona: el node esclau escolta i espera per rebre un "paquet Wake UP". Aquest paquet l’envia el node mestre per demanar dades a l’esclau.

En el meu cas, faig servir una matriu de dos int:

// Paquet despertador

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

Si el meu node rep un paquet,

  1. desperta, llegeix aquest paquet, si el paquet és un "Despert",
  2. genera les dades,
  3. xifrar les dades,
  4. enviar les dades al mestre, esperar un paquet ACK,
  5. dormir.

Per al xifratge AES, faig servir una clau a la ranura número 9.

Aquest és el meu codi per al node esclau

#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;

Estat ATCA_STATUS;

Ràdio RF24 (9, 10);

const uint64_t masteraddresse = 0x1111111111;

const uint64_t slaveaddresse = 0x1111111100;

/**

* / breu Funció executada quan s'estableix la interrupció (IRQ BAIX) * * * / void wakeUpIRQ () {while (radio.available ()) {int data [32]; radio.read (& data, 32); if (dades [0] == 20 && dades [1] == 02) {float temp = 17,6; zumblit flotant = 16,4;

dades uint8_t [16];

uint8_t cypherdata [16];

// Crea una cadena per configurar tot el meu valor

// Cada valor està separat per un "|" i "$" significa el final de les dades // AVÍS: ha de tenir una longitud inferior a 11 String tmp_str_data = String (ID_NODE) + "|" + Cadena (temp, 1) + "|" + Cadena (brunzit, 1) + "$"; // mida 11 Serial.println ("tmp_str_data:" + tmp_str_data);

tmp_str_data.getBytes (dades, mida de (dades));

// Xifra les dades

ATCA_STATUS status = aes_basic_encrypt (& cfg, data, sizeof (data), cypherdata, AES_KEY); if (estat == ATCA_SUCCESS) {llarg rand = aleatori ((llarg) 10000, (llarg) 99999);

// generar un UUID basat en els tres primers nombres = node ID

String uuid = String (ID_NODE) + String (rand); // Mida 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)); // Deixa d’escoltar radio.stopListening ();

bool rslt;

// Envia dades rslt = radio.write (& data_to_send, sizeof (data_to_send)); // Comença a escoltar radio.startListening (); if (rslt) {// Mode final i de suspensió Serial.println (F ("Fet")); }}}}}

configuració nul·la ()

{Serial.begin (9600);

// Inicieu el constructor de la biblioteca

cfg.iface_type = ATCA_I2C_IFACE; // Tipus de comunicació -> Mode I2C cfg.devtype = ATECC608A; // Tipus de xip cfg.atcai2c.slave_address = 0XC0; // Adreça I2C (valor per defecte) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Retard de despert (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 (adreça principal);

radio.openReadingPipe (1, slaveaddresse); // Adjunteu la interrupció al pin 3 // Modifiqueu 1 per O si voleu la interrupció al pin 2 // FALLING MODE = Pin a LOW attachInterrupt (1, wakeUpIRQ, FALLING); }

bucle buit ()

{// No cal}

Node mestre

El node mestre es desperta cada 8 segons per demanar dades al node esclau

Com funciona: el node mestre envia un paquet "WakeUP" a l'esclau i després d'esperar una resposta de l'esclau amb dades.

En el meu cas, faig servir una matriu de dos int:

// Paquet despertador

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

Si el node esclau envia un paquet ACK després que el mestre hagi enviat un paquet WakeUp:

  1. Configuració mestra en mode Escolta i espera una comunicació
  2. Si la comunicació
  3. Extraieu el 8 primer byte, saqueu els tres primers bytes dels 8 bytes, si aquest és el node ID
  4. Extreu els 16 bytes de xifrat
  5. Desxifra les dades
  6. Imprimiu les dades en sèrie
  7. Mode de repòs

Per al xifratge AES, faig servir una clau a la ranura número 9.

Aquest és el meu codi per al node mestre

#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; Estat ATCA_STATUS; Ràdio RF24 (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Paquet Wake UP const int wake_packet [2] = {20, 02}; // ISR d'interrupció del gos de vigilància (WDT_vect) {wdt_disable (); // desactiva watchdog} void sleepmode () {// desactiva ADC ADCSRA = 0; // esborra diverses marques de "restabliment" MCUSR = 0; // permet canvis, inhabilita el restabliment WDTCSR = bit (WDCE) | bit (WDE); // estableix el mode d'interrupció i un interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // defineix WDIE i retarda 8 segons wdt_reset (); // restableix el watchdog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // la seqüència temporitzada segueix sleep_enable (); // desactiva l’activació de marró al programari MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrupcions (); // garanteix la següent instrucció executada sleep_cpu (); // cancel·lar el son com a precaució sleep_disable (); } void setup () {Serial.begin (9600); // Inicieu el constructor de la biblioteca cfg.iface_type = ATCA_I2C_IFACE; // Tipus de comunicació -> Mode I2C cfg.devtype = ATECC608A; // Tipus de xip cfg.atcai2c.slave_address = 0XC0; // Adreça I2C (valor per defecte) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Retard de despert (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, adreça principal); } void loop () {bool rslt; // Enviar dades rslt = radio.write (& wake_packet, sizeof (wake_packet)); if (rslt) {// Comença a escoltar radio.startListening (); while (radio.available ()) {uint8_t resposta [32]; radio.read (& answer, sizeof (answer)); uint8_t node_id [3]; uint8_t cypher [16]; memcpy (node_id, answer, 3); memcpy (cifre, resposta + 3, 16); if ((int) node_id == ID_NODE) {sortida uint8_t [16]; ATCA_STATUS status = aes_basic_decrypt (& cfg, cypher, 16, output, AES_KEY); if (estat == ATCA_SUCCESS) {Serial.println ("Dades desxifrades:"); for (size_t i = 0; i <16; i ++) {Serial.print ((char) output ); }}}}} else {Serial.println ("Ack no rep per Wakup Packet"); } // Mode de repòs 8 segons sleepmode (); }

Si teniu cap pregunta, estic aquí per respondre-la

Pas 4: 4. Aneu més enllà

Aquest exemple és senzill perquè pugueu millorar aquest projecte

Millores:

  • L'AES 128 és bàsic i podeu utilitzar un altre algorisme d'AES com AES CBC per ser més segur.
  • Canvieu el mòdul sense fils (el NRF24L01 està limitat per una càrrega útil de 23 bytes)

Si veieu millores a fer, expliqueu-ho a l'àrea de discussió

Pas 5: Conclusió

Espero que aquest article us sigui útil. Disculpeu si he equivocat el meu text, però l'anglès no és el meu idioma principal i parlo millor del que escric.

Gràcies per llegir-ho tot.

Gaudeix-ho.

Recomanat: