Tabla de contenido:

Comunicación inalámbrica cifrada Arduino: 5 pasos
Comunicación inalámbrica cifrada Arduino: 5 pasos

Video: Comunicación inalámbrica cifrada Arduino: 5 pasos

Video: Comunicación inalámbrica cifrada Arduino: 5 pasos
Video: Generalidades de la comunicación inalámbrica con Arduino. 2024, Mes de julio
Anonim
Comunicación inalámbrica encriptada Arduino
Comunicación inalámbrica encriptada Arduino

Hola, todos, En este segundo artículo te explicaré cómo utilizar el chip Atecc608a para asegurar tu comunicación inalámbrica. Para esto, usaré el NRF24L01 + para la parte inalámbrica y el Arduino UNO.

El microchip ATECC608A ha sido diseñado por MicroChip y tiene múltiples herramientas de seguridad. Por ejemplo, este chip puede almacenar claves ECC, claves AES (para AES 128) y Hash SHA2.

El artículo: NRF24L01 + Arduino UNO + ATECC608A

Durante una comunicación entre dos Objetos de IoT, pueden existir múltiples ataques: Man Of the mild, Copy of information y más.. Entonces mi idea es muy simple:

  1. Utilización de datos cifrados entre dos o más objetos de IoT.
  2. Suministros de bajo costo
  3. Puede trabajar con un Arduino UNO

En mi caso, uso

  • el Atecc608a para almacenar mi clave AES y para cifrar / descifrar mis datos.
  • el Arduino Uno como microcontrolador
  • El NRF24L01 para enviar mis datos

Debe seguir esos pasos para este proyecto:

  1. Configurar el chip ATECC608A
  2. Hacer el circuito (nodo maestro y nodo esclavo)
  3. Parte de código
  4. ¡Ve más lejos!

Para los primeros pasos "Configurar el chip ATECC608A", escribí otro artículo que explica cada paso en orden. El enlace está aquí:

Ahora empezar !

Suministros

Para este proyecto necesitas:

  • 2 Arduino UNO o Arduino NANO o Arduino Mega
  • Algo de alambre
  • 2 Atecc608a (cada uno cuesta menos de 0,60 $)
  • 2 NRF24L01 +
  • 2 condensadores (10 μF)
  • Tableros de pruebas

Enlace a mi artículo que explica cómo configurar el chip ATECC608A -> Cómo configurar Atecc608a

Paso 1: 1. Configure el Atecc608a

1. Configure el Atecc608a
1. Configure el Atecc608a
1. Configure el Atecc608a
1. Configure el Atecc608a

No detallaré cada paso a seguir para configurar un ATECC608A porque escribí un artículo completo que explica todos los pasos para hacerlo. Para configurarlo, debe seguir el "Paso 4" de este artículo llamado "2. Configuración del Chip (Atecc608a)"

El enlace es: Cómo configurar un ATECC608A

Además, debe poner la misma configuración para el Atecc608a, el lado maestro y el lado esclavo, de lo contrario no podrá descifrar sus datos

Advertencia:

Para configurar este chip, debe seguir todos los pasos del artículo anterior en orden. Si falta un paso o el chip no está bloqueado, no podrá realizar este proyecto

Recordatorio:

Paso a seguir para esto:

  • Crea una plantilla de configuración
  • Escribe esta plantilla en el chip
  • Bloquear la zona de configuración
  • Escriba su clave AES (128 Bits) en una ranura
  • Bloquear la zona de datos

Paso 2: 2. Diseño del circuito (maestro y esclavo)

2. Diseño del circuito (maestro y esclavo)
2. Diseño del circuito (maestro y esclavo)
2. Diseño del circuito (maestro y esclavo)
2. Diseño del circuito (maestro y esclavo)

En este proyecto, tendrá un nodo maestro y un nodo esclavo.

El nodo maestro imprimirá los datos enviados por el nodo esclavo en claro. Solicitará datos del nodo esclavo cada X veces.

El nodo esclavo escuchará la "red" y cuando reciba una "Solicitud de datos", la generará, la cifrará y la enviará al nodo maestro.

Para ambos lados, maestro y esclavo, el circuito es el mismo:

  • Un arduino Nano
  • Un ATECC608A
  • Un NRF24L01

Adjunté el circuito a este paso (ver imagen de arriba).

Para el ATECC608A al Arduino UNO, este es un soic de 8 pines. Agregué la "vista superior" arriba:

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

Para el NRF24L01 al 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) -> solo para nodo esclavo, no usado en modo maestro

Por qué utilizar el pin IRQ del NRF24L01

El pin IRQ es muy útil, este pin permite decir (BAJO) cuando el NRF24L01 recibe un paquete, por lo que podemos conectar una Interrupción a este pin para despertar el nodo esclavo.

Paso 3: 3. el código (esclavo y maestro)

3. el código (esclavo y maestro)
3. el código (esclavo y maestro)

Nodo esclavo

Utilizo el ahorro de energía para el nodo esclavo porque no necesita escuchar todo el tiempo.

Cómo funciona: el nodo esclavo escucha y espera recibir un "paquete Wake UP". Este paquete es enviado por el nodo maestro para pedir datos al esclavo.

En mi caso, uso una matriz de dos int:

// Despertar paquete

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

Si mi nodo recibe un paquete,

  1. se despierta, lee este paquete, si el paquete es un "Wake UP",
  2. genera los datos,
  3. cifrar los datos,
  4. envíe los datos al maestro, espere un paquete ACK,
  5. dormir.

Para el cifrado AES, utilizo una clave en la ranura número 9.

Este es mi código para el nodo esclavo

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

Estado ATCA_STATUS;

Radio RF24 (9, 10);

const uint64_t masteraddresse = 0x1111111111;

const uint64_t slaveaddresse = 0x1111111100;

/**

* / función breve ejecutada cuando se establece la interrupción (IRQ LOW) * * * / void wakeUpIRQ () {while (radio.available ()) {int data [32]; radio.read (& datos, 32); if (data [0] == 20 && data [1] == 02) {float temp = 17.6; zumbido de flotación = 16,4;

uint8_t datos [16];

uint8_t cypherdata [16];

// Construir una cadena para establecer todos mis valores

// Cada valor está separado por un "|" y el "$" significa el final de los datos // ADVERTENCIA: Debe tener menos de 11 de longitud String tmp_str_data = String (ID_NODE) + "|" + Cadena (temp, 1) + "|" + Cadena (zumbido, 1) + "$"; // tamaño de 11 Serial.println ("tmp_str_data:" + tmp_str_data);

tmp_str_data.getBytes (datos, tamaño de (datos));

// Cifrar los datos

ATCA_STATUS status = aes_basic_encrypt (& cfg, datos, tamaño de (datos), cypherdata, AES_KEY); if (estado == ATCA_SUCCESS) {rand largo = aleatorio ((largo) 10000, (largo) 99999);

// generar un UUID basado en los tres primeros números = ID nodo

String uuid = String (ID_NODE) + String (rand); // Tamaño de 8

uint8_t tmp_uuid [8];

uint8_t datos_enviar [32];

uuid.getBytes (tmp_uuid, tamaño de (tmp_uuid) + 1);

memcpy (datos_para_enviar, tmp_uuid, tamaño de (tmp_uuid));

memcpy (data_to_send + sizeof (tmp_uuid), cypherdata, sizeof (cypherdata)); // Deja de escuchar radio.stopListening ();

bool rslt;

// Enviar datos rslt = radio.write (& data_to_send, sizeof (data_to_send)); // Empezar a escuchar radio.startListening (); if (rslt) {// Fin y modo de suspensión Serial.println (F ("Listo")); }}}}}

configuración vacía ()

{Serial.begin (9600);

// Inicia el constructor de la biblioteca

cfg.iface_type = ATCA_I2C_IFACE; // Tipo de comunicación -> Modo I2C cfg.devtype = ATECC608A; // Tipo de chip cfg.atcai2c.slave_address = 0XC0; // Dirección I2C (valor predeterminado) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Retraso de despertar (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 (dirección maestra);

radio.openReadingPipe (1, dirección esclava); // Adjuntar interrupción al pin 3 // Modificar 1 por O si desea que la interrupción al pin 2 // FALLING MODE = Pin en LOW attachInterrupt (1, wakeUpIRQ, FALLING); }

bucle vacío ()

{ // No hay necesidad }

Nodo maestro

El nodo maestro se despierta cada 8 segundos para pedir datos al nodo esclavo

Cómo funciona: El nodo maestro envía un paquete "WakeUP" al esclavo y luego espera una respuesta del esclavo con datos.

En mi caso, uso una matriz de dos int:

// Despertar paquete

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

Si el nodo esclavo envía un paquete ACK después de que el maestro envió un paquete WakeUp:

  1. Maestro configurado en modo Escuchar y esperar una comunicación
  2. Si la comunicación
  3. Extraiga los 8 primeros bytes, saquee los tres primeros bytes de los 8 bytes, si este es el nodo de ID
  4. Extrae los 16 bytes de cifrado
  5. Descifrar los datos
  6. Imprime los datos en serie
  7. Modo de sueño

Para el cifrado AES, utilizo una clave en la ranura número 9.

Este es mi código para el nodo maestro

#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; Estado ATCA_STATUS; Radio RF24 (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Despertar paquete const int wake_packet [2] = {20, 02}; // ISR de interrupción del perro guardián (WDT_vect) {wdt_disable (); // deshabilita el perro guardián} void sleepmode () {// deshabilita ADC ADCSRA = 0; // borrar varios indicadores de "reinicio" MCUSR = 0; // permitir cambios, deshabilitar restablecer WDTCSR = bit (WDCE) | bit (WDE); // establece el modo de interrupción y un intervalo WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // establece WDIE y 8 segundos de retraso wdt_reset (); // restablece el perro guardián set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // la secuencia cronometrada sigue a sleep_enable (); // desactivar la habilitación de la caída de tensión en el software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrumpe (); // garantiza la siguiente instrucción ejecutada sleep_cpu (); // cancela el sueño como medida de precaución sleep_disable (); } configuración vacía () {Serial.begin (9600); // Inicia el constructor de la biblioteca cfg.iface_type = ATCA_I2C_IFACE; // Tipo de comunicación -> Modo I2C cfg.devtype = ATECC608A; // Tipo de chip cfg.atcai2c.slave_address = 0XC0; // Dirección I2C (valor predeterminado) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Retraso de despertar (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 (esclavoaddresse); radio.openReadingPipe (1, dirección maestra); } bucle vacío () {bool rslt; // Enviar datos rslt = radio.write (& wake_packet, sizeof (wake_packet)); if (rslt) {// Empezar a escuchar radio.startListening (); while (radio.available ()) {uint8_t answer [32]; radio.read (& respuesta, tamaño de (respuesta)); uint8_t id_nodo [3]; uint8_t cifrado [16]; memcpy (id_nodo, respuesta, 3); memcpy (cifrado, respuesta + 3, 16); if ((int) node_id == ID_NODE) {uint8_t salida [16]; ATCA_STATUS status = aes_basic_decrypt (& cfg, cypher, 16, salida, AES_KEY); if (estado == ATCA_SUCCESS) {Serial.println ("Datos descifrados:"); for (size_t i = 0; i <16; i ++) {Serial.print ((char) output ); }}}}} else {Serial.println ("Ack no recibir para Wakup Packet"); } // Modo de reposo 8 segundos modo de reposo (); }

Si tiene alguna pregunta, ¡estoy aquí para responderla

Paso 4: 4. ¡Vaya más lejos

Este ejemplo es simple para que pueda mejorar este proyecto.

Mejoras:

  • El AES 128 es básico y puedes usar otro algoritmo de AES como AES CBC para estar más seguro.
  • Cambie el módulo inalámbrico (el NRF24L01 está limitado por una carga útil de 23 bytes)

Si ve alguna mejora que hacer, explíquela en el área de discusión.

Paso 5: Conclusión

Espero que este artículo te sea de utilidad. Perdón si me equivoqué en mi texto, pero el inglés no es mi idioma principal y hablo mejor de lo que escribo.

Gracias por leer todo.

Disfrútala.

Recomendado: