Table des matières:
- Fournitures
- Étape 1: 1. Configurer l'Atecc608a
- Étape 2: 2. Conception du circuit (maître et esclave)
- Étape 3: 3. le Code (Esclave et Maître)
- Étape 4: 4. Allez plus loin
- Étape 5: Conclusion
Vidéo: Communication cryptée sans fil Arduino : 5 étapes
2024 Auteur: John Day | [email protected]. Dernière modifié: 2024-01-30 09:06
Bonjour à tous, Dans ce deuxième article, je vais vous expliquer comment utiliser la puce Atecc608a pour sécuriser votre communication sans fil. Pour cela, j'utiliserai le NRF24L01+ pour la partie Wireless et l'Arduino UNO.
La micropuce ATECC608A a été conçue par MicroChip et dispose de plusieurs outils de sécurité. Par exemple, cette puce peut stocker des clés ECC, des clés AES (pour AES 128) et du hachage SHA2.
L'article: NRF24L01 + Arduino UNO + ATECC608A
Lors d'une communication entre deux objets IoT, plusieurs attaques peuvent exister: Man Of the mild, Copy of information et plus.. Donc mon idée est très simple:
- Utilisation de données cryptées entre deux ou plusieurs objets IoT.
- Fournitures à faible coût
- Peut fonctionner avec un Arduino UNO
Dans mon cas, j'utilise
- l'Atecc608a pour stocker ma clé AES et crypter/décrypter mes données.
- l'Arduino Uno comme microcontrôleur
- Le NRF24L01 pour envoyer mes données
Vous devez suivre ces étapes pour ce projet:
- Configurer la puce ATECC608A
- Faire le circuit (nœud maître et nœud esclave)
- Partie de code
- Aller plus loin !
Pour les premières étapes "Configurer la puce ATECC608A", j'ai écrit un autre article qui explique chaque étape dans l'ordre. Le lien est ici:
Commencez maintenant !
Fournitures
Pour ce projet il vous faut:
- 2 Arduino UNO ou Arduino NANO ou Arduino Mega
- du fil
- 2 Atecc608a (chacun coûtant moins de 0.60$)
- 2 NRF24L01+
- 2 condensateurs (10 F)
- Planches à pain
Lien vers mon article qui explique comment paramétrer la puce ATECC608A -> Comment paramétrer Atecc608a
Étape 1: 1. Configurer l'Atecc608a
Je ne détaillerai pas toutes les étapes à suivre pour mettre en place un ATECC608A car j'ai écrit un article complet qui explique toutes les étapes pour le faire. Pour le mettre en place, vous devez suivre l'« Étape 4 » de cet article intitulé « 2. Configuration de la puce (Atecc608a) »
Le lien est: Comment configurer un ATECC608A
De plus, vous devez mettre la même configuration pour l'Atecc608a, côté maître et côté esclave, sinon vous ne pourrez pas déchiffrer vos données
Avertissement:
Pour configurer cette puce, vous devez suivre toutes les étapes de l'article ci-dessus dans l'ordre. S'il manque une étape ou si la puce n'est pas verrouillée, vous ne pourrez pas réaliser ce projet
Reste:
Etape à suivre pour cela:
- Créer un modèle de configuration
- Écrivez ce modèle sur la puce
- Verrouiller la zone de configuration
- Écrivez votre clé AES (128 bits) dans un emplacement
- Verrouiller la zone de données
Étape 2: 2. Conception du circuit (maître et esclave)
Dans ce projet, vous aurez un nœud maître et un nœud esclave.
Le nœud maître imprimera les données envoyées par le nœud esclave en clair. Il demandera des données au nœud esclave à chaque fois X.
Le nœud esclave écoutera le "réseau" et lorsqu'il recevra une "Demande de données", il la générera, la cryptera et l'enverra au nœud maître.
Pour les deux côtés, maître et esclave le circuit est le même:
- Un arduino Nano
- Un ATECC608A
- Un NRF24L01
J'ai attaché le circuit à cette étape (cf photo ci-dessus).
Pour l'ATECC608A vers l'Arduino UNO, il s'agit d'un soic 8 broches. J'ai ajouté la "vue de dessus" ci-dessus:
- ARDUINO 3.3V -> BROCHE 8 (Atecc608a)
- ARDUINO GND -> PIN 4 (Atecc608a)
- ARDUINO A4 (SDL) -> PIN 5 (Atecc608a)
- ARDUINO A5 (SCL) -> PIN 6 (Atecc608a)
Pour le NRF24L01 à 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) -> uniquement pour le nœud esclave, non utilisé en mode maître
Pourquoi utiliser la broche IRQ du NRF24L01
La broche IRQ est très utile, cette broche permet de dire (LOW) quand un paquet est reçu par le NRF24L01, on peut donc attacher une interruption à cette broche pour réveiller le nœud esclave.
Étape 3: 3. le Code (Esclave et Maître)
Nœud esclave
J'utilise l'économie d'énergie pour le nœud esclave car il n'a pas besoin d'écouter tout le temps.
Comment ça marche: le nœud esclave écoute et attend de recevoir un "Wake UP packet". Ce paquet est envoyé par le nœud maître pour demander des données à l'esclave.
Dans mon cas, j'utilise un tableau de deux int:
// Paquet de réveil
const int wake_packet[2] = {20, 02};
Si mon nœud reçoit un paquet,
- il se réveille, lisez ce paquet, si le paquet est un "Wake UP",
- il génère les données,
- crypter les données,
- envoyer les données au maître, attendre un paquet ACK,
- dormir.
Pour le cryptage AES, j'utilise une clé dans le slot numéro 9.
Ceci est mon code pour le nœud esclave
#include "Arduino.h"#include "avr/sleep.h" #include "avr/wdt.h"
#include "SPI.h"
#inclure "nRF24L01.h" #inclure "RF24.h"
#include "Fil.h"
// Bibliothèque ATECC608A
#include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h"
#define ID_NODE 255
#define AES_KEY (uint8_t)9
ATCAIfaceCfg cfg;
état ATCA_STATUS;
radio RF24 (9, 10);
const uint64_t adresse maître = 0x1111111111;
const uint64_t adresse esclave = 0x1111111100;
/**
* \brief Fonction exécutée lorsque l'interruption est définie (IRQ LOW) * * */ void wakeUpIRQ() { while (radio.available()) { int data[32]; radio.read(&data, 32); if (data[0] == 20 && data[1] == 02) { float temp = 17,6; bourdonnement flottant = 16,4;
uint8_t données[16];
uint8_t cypherdata[16];
// Construire une chaîne pour définir toute ma valeur
// Chaque valeur est séparée par un "|" et le "$" signifie la fin des données // ATTENTION: Doit être inférieur à 11 String tmp_str_data = String(ID_NODE) + "|" + Chaîne(temp, 1) + "|" + Chaîne(hum, 1) + "$"; //taille de 11 Serial.println("tmp_str_data: " + tmp_str_data);
tmp_str_data.getBytes(data, sizeof(data));
// Crypter les données
ATCA_STATUS status = aes_basic_encrypt(&cfg, data, sizeof(data), cypherdata, AES_KEY); if (statut == ATCA_SUCCESS) { long rand = random((long)10000, (long)99999);
// générer un UUID basé sur les trois premiers nombres = nœud ID
Chaîne uuid = Chaîne(ID_NODE) + Chaîne(rand); // Taille 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)); // Arrête d'écouter radio.stopListening();
bool rslt;
// Envoi des données rslt = radio.write(&data_to_send, sizeof(data_to_send)); // Commencer à écouter radio.startListening(); if (rslt) { // Fin et mode veille Serial.println(F("Done")); } } } } }
void setup()
{ Serial.begin(9600);
// Initialisation du constructeur de la librairie
cfg.iface_type = ATCA_I2C_IFACE; // Type de communication -> Mode I2C cfg.devtype = ATECC608A; // Type de puce cfg.atcai2c.slave_address = 0XC0; // Adresse I2C (valeur par défaut) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Délai de réveil (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(adresse principale);
radio.openReadingPipe(1, adresse esclave); // Attachez l'interruption à la broche 3 // Modifiez 1 par O si vous voulez l'interruption à la broche 2 // FALLING MODE = Pin at LOW attachInterrupt(1, wakeUpIRQ, FALLING); }
boucle vide()
{ // Ce n'est pas nécessaire }
Nœud maître
Le nœud maître se réveille toutes les 8 secondes pour demander des données au nœud esclave
Comment ça marche: Le nœud maître envoie un paquet "WakeUP" à l'esclave et attend une réponse de l'esclave avec des données.
Dans mon cas, j'utilise un tableau de deux int:
// Paquet de réveil
const int wake_packet[2] = {20, 02};
Si le nœud esclave envoie un paquet ACK après que le maître ait envoyé un paquet WakeUp:
- Le maître s'installe en mode écoute et attend une communication
- Si la communication
- Extraire les 8 premiers octets, piller les trois premiers octets des 8 octets, s'il s'agit du nœud ID
- Extraire les 16 octets de chiffrement
- Décrypter les données
- Imprimer les données en série
- Mode veille
Pour le cryptage AES, j'utilise une clé dans le slot numéro 9.
Ceci est mon code pour le nœud maître
#include "Arduino.h"
#include "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // bibliothèque ATECC608A #include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h" #define ID_NODE 255 #define AES_KEY (uint8_t)9 ATCAIfaceCfg cfg; état ATCA_STATUS; radio RF24 (9, 10); const uint64_t adresse maître = 0x1111111111; const uint64_t adresse esclave = 0x1111111100; // Wake UP packet const int wake_packet[2] = {20, 02}; // interruption du chien de garde ISR(WDT_vect) { wdt_disable(); // désactiver le chien de garde } void sleepmode() { // désactiver l'ADC ADCSRA = 0; // efface divers drapeaux "reset" MCUSR = 0; // autoriser les modifications, désactiver la réinitialisation WDTCSR = bit(WDCE) | bit(WDE); // définit le mode d'interruption et un intervalle WDTCSR = bit(WDIE) | bits(WDP3) | bit(WDP0); // définit WDIE et retarde de 8 secondes wdt_reset(); // réinitialiser le chien de garde set_sleep_mode(SLEEP_MODE_PWR_DOWN); noInterrupts(); // la séquence chronométrée suit sleep_enable(); // désactiver l'activation du brown-out dans le logiciel MCUCR = bit(BODS) | bit(BODSE); MCUCR = bit(BODS); interruptions(); // garantit la prochaine instruction exécutée sleep_cpu(); // annule le sommeil par précaution sleep_disable(); } void setup() { Serial.begin(9600); // Init le constructeur pour la bibliothèque cfg.iface_type = ATCA_I2C_IFACE; // Type de communication -> Mode I2C cfg.devtype = ATECC608A; // Type de puce cfg.atcai2c.slave_address = 0XC0; // Adresse I2C (valeur par défaut) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Délai de réveil (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(slaveaddress); radio.openReadingPipe(1, adresse principale); } boucle vide() { bool rslt; // Envoi des données rslt = radio.write(&wake_packet, sizeof(wake_packet)); if (rslt) { // Démarrer l'écoute radio.startListening(); while (radio.available()) { uint8_t answer[32]; radio.read(&answer, sizeof(answer)); uint8_t node_id[3]; uint8_t cypher[16]; memcpy(node_id, réponse, 3); memcpy(chiffre, réponse + 3, 16); if ((int)node_id == ID_NODE) { uint8_t sortie[16]; ATCA_STATUS status = aes_basic_decrypt(&cfg, cypher, 16, sortie, AES_KEY); if (status == ATCA_SUCCESS) { Serial.println("Decrypted Data: "); for (size_t i = 0; i < 16; i++) { Serial.print((char)output); } } } } } else{ Serial.println("Ack not receive for Wakup Packet"); } // Mode veille 8 secondes mode veille(); }
Si vous avez une question, je suis là pour y répondre
Étape 4: 4. Allez plus loin
Cet exemple est simple donc vous pouvez améliorer ce projet
Améliorations:
- L'AES 128 est basique et vous pouvez utiliser un autre algorithme d'AES comme AES CBC pour être plus sûr.
- Changer le module sans fil (le NRF24L01 est limité par une charge utile de 23 octets)
- …
Si vous voyez des améliorations à faire, expliquez-les sur l'espace de discussion
Étape 5: Conclusion
J'espère que cet article vous sera utile. Désolé si je me suis trompé dans mon texte mais l'anglais n'est pas ma langue principale et je parle mieux que j'écris.
Merci d'avoir tout lu.
Profitez-en.
Conseillé:
Robot Arduino sans fil utilisant le module sans fil HC12 : 7 étapes
Robot Arduino sans fil utilisant le module sans fil HC12 : Salut les gars, bon retour. Dans mon article précédent, j'ai expliqué ce qu'est un circuit de pont en H, un circuit intégré de pilote de moteur L293D, un circuit de pilote de moteur L293D superposé pour piloter des pilotes de moteur à courant élevé et comment vous pouvez concevoir et fabriquer votre propre carte de pilote de moteur L293D
Longue portée, 1,8 km, communication sans fil Arduino à Arduino avec le HC-12. : 6 étapes (avec photos)
Longue portée, 1,8 km, communication sans fil Arduino à Arduino avec le HC-12.: Dans cette instruction, vous apprendrez à communiquer entre Arduinos sur une longue distance jusqu'à 1,8 km en plein air. Le HC-12 est un port série sans fil module de communication très utile, extrêmement puissant et simple d'utilisation. Vous allez d'abord lea
Point d'accès sans fil de 50 mètres de portée avec adaptateur sans fil USB TP Link WN7200ND sur Raspbian Stretch: 6 étapes
Point d'accès sans fil de 50 mètres de portée avec adaptateur sans fil USB TP Link WN7200ND sur Raspbian Stretch : Raspberry Pi est idéal pour créer des points d'accès sans fil sécurisés mais il n'a pas une bonne portée, j'ai utilisé un adaptateur sans fil USB TP Link WN7200ND pour l'étendre. Je veux partager comment le fairePourquoi est-ce que je veux utiliser un Raspberry Pi au lieu d'un routeur ?T
Système DIY de micro sans fil pour guitare sans fil : 4 étapes
DIY Wireless Mic to Wireless Guitar System: J'ai regardé des vidéos et des groupes et presque tous utilisent un système sans fil à la guitare. Devenir fou, bouger, marcher et faire ce qu'ils veulent sans le cordon alors je rêve d'en avoir un.. Mais.. pour moi maintenant c'est trop cher alors je suis arrivé à ça
Pirater une sonnette sans fil dans un interrupteur d'alarme sans fil ou un interrupteur marche/arrêt : 4 étapes
Piratage d'une sonnette sans fil dans un interrupteur d'alarme sans fil ou un interrupteur marche/arrêt : j'ai récemment construit un système d'alarme et je l'ai installé dans ma maison. J'ai utilisé des interrupteurs magnétiques sur les portes et les ai câblés à travers le grenier. Les fenêtres étaient une autre histoire et leur câblage n'était pas une option. J'avais besoin d'une solution sans fil et c'est