Spisu treści:
- Kieszonkowe dzieci
- Krok 1: 1. Skonfiguruj Atecc608a
- Krok 2: 2. Projekt obwodu (nadrzędny i podrzędny)
- Krok 3: 3. Kod (Slave i Master)
- Krok 4: 4. Idź dalej
- Krok 5: Wniosek
Wideo: Szyfrowana komunikacja bezprzewodowa Arduino: 5 kroków
2024 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2024-01-30 11:28
Cześć wszystkim, W tym drugim artykule wyjaśnię, jak wykorzystać chip Atecc608a do zabezpieczenia komunikacji bezprzewodowej. W tym celu użyję NRF24L01+ dla części bezprzewodowej i Arduino UNO.
Mikrochip ATECC608A został zaprojektowany przez MicroChip i posiada wiele narzędzi zabezpieczających. Na przykład ten układ może przechowywać klucze ECC, klucze AES (dla AES 128) i skrót SHA2.
Artykuł: NRF24L01 + Arduino UNO + ATECC608A
Podczas komunikacji między dwoma obiektami IoT może wystąpić wiele ataków: Man Of the mild, Copy of information i więcej.. Mój pomysł jest więc bardzo prosty:
- Wykorzystanie zaszyfrowanych danych między dwoma lub więcej obiektami IoT.
- Tanie materiały eksploatacyjne
- Może współpracować z Arduino UNO
W moim przypadku używam
- Atecc608a do przechowywania mojego klucza AES i szyfrowania/odszyfrowywania moich danych.
- Arduino Uno jako mikrokontroler
- NRF24L01 do wysłania moich danych
Musisz wykonać te kroki dla tego projektu:
- Skonfiguruj układ ATECC608A
- Wykonaj obwód (węzeł główny i węzeł podrzędny)
- Część kodu
- Idź dalej !
W przypadku pierwszych kroków „Ustaw układ ATECC608A” napisałem inny artykuł, który wyjaśnia każdy krok w kolejności. Link jest tutaj:
Teraz zacznij!
Kieszonkowe dzieci
Do tego projektu potrzebujesz:
- 2 Arduino UNO lub Arduino NANO lub Arduino Mega
- Niektóre druty
- 2 Atecc608a (każdy kosztuje mniej niż 0,60$)
- 2 NRF24L01+
- 2 kondensatory (10 μF)
- Deski do krojenia chleba
Link do mojego artykułu wyjaśniającego jak skonfigurować układ ATECC608A -> Jak skonfigurować Atecc608a
Krok 1: 1. Skonfiguruj Atecc608a
Nie będę szczegółowo opisywał każdego kroku, który należy wykonać, aby skonfigurować ATECC608A, ponieważ napisałem pełny artykuł, który wyjaśnia wszystkie kroki, aby to zrobić. Aby to skonfigurować, musisz wykonać „Krok 4” tego artykułu zatytułowany „2. Konfiguracja układu (Atecc608a)”
Link to: jak skonfigurować ATECC608A?
Ponadto musisz wprowadzić tę samą konfigurację dla Atecc608a, po stronie master i slave, w przeciwnym razie nie będziesz w stanie odszyfrować swoich danych
Ostrzeżenie:
Aby skonfigurować ten chip, musisz wykonać kolejno wszystkie kroki powyższego artykułu. Jeśli brakuje jednego kroku lub chip nie jest zablokowany, nie będziesz w stanie wykonać tego projektu
Pozostała część:
Krok do naśladowania w tym celu:
- Utwórz szablon konfiguracji
- Napisz ten szablon do chipa
- Zablokuj strefę konfiguracji
- Wpisz swój klucz AES (128 bitów) w gnieździe
- Zablokuj strefę danych
Krok 2: 2. Projekt obwodu (nadrzędny i podrzędny)
W tym projekcie będziesz miał węzeł główny i węzeł podrzędny.
Węzeł główny wydrukuje dane wysłane przez węzeł podrzędny w postaci wyraźnej. Co X będzie żądać danych od węzła podrzędnego.
Węzeł podrzędny będzie nasłuchiwał „sieci”, a gdy otrzyma „dane żądania”, wygeneruje je, zaszyfruje i wyśle do węzła głównego.
Dla obu stron, master i slave, obwód jest taki sam:
- Jeden arduino Nano
- Jeden ATECC608A
- Jeden NRF24L01
Do tego kroku podłączyłem obwód (por. obrazek powyżej).
Dla ATECC608A do Arduino UNO jest to soic 8 pin. Dodałem "widok z góry" powyżej:
- ARDUINO 3,3V -> PIN 8 (Atecc608a)
- ARDUINO GND -> PIN 4 (Atecc608a)
- ARDUINO A4 (SDL) -> PIN 5 (Atecc608a)
- ARDUINO A5 (SCL) -> PIN 6 (Atecc608a)
Dla NRF24L01 do 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) -> tylko dla węzła Slave, nieużywane w trybie Master
Dlaczego warto używać pinu IRQ w NRF24L01?
Pin IRQ jest bardzo przydatny, ten pin pozwala powiedzieć (LOW), kiedy pakiet zostanie odebrany przez NRF24L01, więc możemy dołączyć przerwanie do tego pinu, aby obudzić węzeł podrzędny.
Krok 3: 3. Kod (Slave i Master)
Węzeł podrzędny
Używam oszczędzania energii dla węzła podrzędnego, ponieważ nie musi on cały czas nasłuchiwać.
Jak to działa: węzeł podrzędny nasłuchuje i czeka na otrzymanie pakietu „Wake UP”. Ten pakiet jest wysyłany przez węzeł nadrzędny w celu zażądania danych od urządzenia podrzędnego.
W moim przypadku używam tablicy dwóch int:
// Pakiet wybudzania
const int wake_packet[2] = {20, 02};
Jeśli mój węzeł otrzyma pakiet,
- obudzi się, odczytaj ten pakiet, jeśli pakiet jest "Wake UP",
- generuje dane,
- szyfrować dane,
- wyślij dane do mastera, poczekaj na pakiet ACK,
- spać.
Do szyfrowania AES używam klucza w slocie numer 9.
To jest mój kod dla węzła Slave
#include "Arduino.h"#include "avr/sleep.h" #include "avr/wdt.h"
#include "SPI.h"
#include "nRF24L01.h" #include "RF24.h"
#include "Drut.h"
// Biblioteka ATECC608A
#include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h"
#define ID_NODE 255
#define AES_KEY (uint8_t)9
ATCAIfaceCfg cfg;
status ATCA_STATUS;
radio RF24 (9, 10);
const uint64_t masteraddresse = 0x1111111111;
const uint64_t slaveaddresse = 0x11111111100;
/**
* \brief Funkcja wykonywana po ustawieniu przerwania (IRQ LOW) * * */ void wakeUpIRQ() { while (radio.available()) { int data[32]; radio.odczyt(&dane, 32); if (data[0] == 20 && data[1] == 02) { float temp = 17,6; szum pływaka = 16,4;
dane uint8_t[16];
zaszyfrowane dane uint8_t[16];
// Zbuduj ciąg, aby ustawić całą moją wartość
// Każda wartość jest oddzielona znakiem „|” a "$" oznacza koniec danych // UWAGA: Musi mieć mniej niż 11 długości String tmp_str_data = String(ID_NODE) + "|" + String(temp, 1) + "|" + String(hum, 1) + "$"; //rozmiar 11 Serial.println("tmp_str_data: " + tmp_str_data);
tmp_str_data.getBytes(dane, sizeof(dane));
// Zaszyfruj dane
ATCA_STATUS status = aes_basic_encrypt(&cfg, dane, sizeof(dane), cypherdata, AES_KEY); if (status == ATCA_SUCCESS) { long rand = random((long)10000, (long)99999);
// wygeneruj UUID na podstawie trzech pierwszych liczb = ID węzła
Ciąg uuid = Ciąg (ID_NODE) + Ciąg (rand); // Rozmiar 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)); // Przestań słuchać radia.stopListening();
bool rslt;
// Wyślij dane rslt = radio.write(&data_to_send, sizeof(data_to_send)); // Rozpocznij słuchanie radio.startListening(); if (rslt) { // Koniec i tryb uśpienia Serial.println(F("Gotowe")); } } } } }
pusta konfiguracja()
{ Szeregowy.początek(9600);
// Uruchom konstruktora biblioteki
cfg.iface_type = ATCA_I2C_IFACE; // Rodzaj komunikacji -> tryb I2C cfg.devtype = ATECC608A; // Typ chipa cfg.atcai2c.slave_address = 0XC0; // adres I2C (wartość domyślna) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Opóźnienie budzenia (1500 ms) cfg.rx_retries = 20;
radio.początek();
radio.setDataRate(RF24_250KBPS); radio.maskIRQ(1, 1, 0); radio.enableAckPayload(); radio.setRetries(5, 5);
radio.openWritingPipe(adres główny);
radio.openReadingPipe(1, adres niewolnika); // Dołącz przerwanie do pinu 3 // Zmodyfikuj 1 przez O jeśli chcesz przerwać na pin 2 // FALLING MODE = Pin at LOW attachInterrupt(1, wakeUpIRQ, FALLING); }
pusta pętla()
{ // Nie ma potrzeby }
Węzeł główny
Węzeł główny budzi się co 8 sekund, aby poprosić o dane z węzła podrzędnego
Jak to działa: Węzeł główny wysyła pakiet „WakeUP” do urządzenia podrzędnego, a po odczekaniu odpowiedzi urządzenia podrzędnego z danymi.
W moim przypadku używam tablicy dwóch int:
// Pakiet wybudzania
const int wake_packet[2] = {20, 02};
Jeśli węzeł podrzędny wyśle pakiet ACK po tym, jak master wysłał pakiet WakeUp:
- Konfiguracja Master w trybie słuchania i czekanie na komunikację
- Jeśli komunikacja
- Wyodrębnij 8 pierwszych bajtów, zdobądź trzy pierwsze bajty z 8 bajtów, jeśli jest to węzeł ID
- Wyodrębnij 16 bajtów szyfru
- Odszyfruj dane
- Wydrukuj dane w serialu
- Tryb uśpienia
Do szyfrowania AES używam klucza w slocie numer 9.
To jest mój kod dla węzła głównego
#include "Arduino.h"
#include "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // Biblioteka ATECC608A #include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h" #define ID_NODE 255 #define AES_KEY (uint8_t)9 ATCAIfaceCfg cfg; status ATCA_STATUS; radio RF24 (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x11111111100; // Pakiet budzenia const int wake_packet[2] = {20, 02}; // watchdog przerwanie ISR(WDT_vect) { wdt_disable(); // wyłącz watchdog } void tryb uśpienia() { // wyłącz ADC ADCSRA = 0; // wyczyść różne flagi "resetu" MCUSR = 0; // zezwól na zmiany, wyłącz resetowanie WDTCSR = bit(WDCE) | bit(WDE); // ustaw tryb przerwania i interwał WDTCSR = bit(WDIE) | bit(WDP3) | bit(WDP0); // ustaw WDIE i 8 sekund opóźnienia wdt_reset(); // zresetuj watchdoga set_sleep_mode(SLEEP_MODE_PWR_DOWN); bez przerwań(); // sekwencja czasowa następuje po sleep_enable(); // wyłącz włączanie brown-out w oprogramowaniu MCUCR = bit(BODS) | bit (BODSE); MCUCR = bit (BODS); przerwania(); // gwarantuje wykonanie następnej instrukcji sleep_cpu(); // zapobiegawczo anuluj sen sleep_disable(); } void setup() { Serial.begin(9600); // Uruchom konstruktora biblioteki cfg.iface_type = ATCA_I2C_IFACE; // Rodzaj komunikacji -> tryb I2C cfg.devtype = ATECC608A; // Typ chipa cfg.atcai2c.slave_address = 0XC0; // adres I2C (wartość domyślna) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Opóźnienie budzenia (1500 ms) cfg.rx_retries = 20; radio.początek(); radio.setDataRate(RF24_250KBPS); radio.maskIRQ(1, 1, 0); radio.enableAckPayload(); radio.setRetries(5, 5); radio.openWritingPipe(slaveaddresse); radio.openReadingPipe(1,adres główny); } void loop() { bool rslt; // Wyślij dane rslt = radio.write(&wake_packet, sizeof(wake_packet)); if (rslt) { // Rozpocznij słuchanie radio.startListening(); while (radio.available()) { uint8_t answer[32]; radio.read(&odpowiedź, sizeof(odpowiedź)); uint8_t id_węzła[3]; szyfr uint8_t[16]; memcpy(node_id, odpowiedź, 3); memcpy(cyfr, odpowiedź + 3, 16); if ((int)node_id == ID_NODE) { wyjście uint8_t[16]; ATCA_STATUS status = aes_basic_decrypt(&cfg, szyfr, 16, wyjście, AES_KEY); if (status == ATCA_SUCCESS) { Serial.println("Odszyfrowane dane: "); for (size_t i = 0; i < 16; i++) { Serial.print((char)output); } } } } } else{ Serial.println("Potwierdzenie braku odbioru pakietu Wakup"); } // Tryb uśpienia 8 sekund tryb uśpienia(); }
Jeśli masz pytanie, jestem tutaj, aby na nie odpowiedzieć
Krok 4: 4. Idź dalej
Ten przykład jest prosty, więc możesz ulepszyć ten projekt
Ulepszenia:
- AES 128 jest podstawowym i możesz użyć innego algorytmu AES jako AES CBC, aby być bezpieczniejszym.
- Zmień moduł bezprzewodowy (NRF24L01 jest ograniczony ładownością 23 bajtów)
- …
Jeśli widzisz poprawę do zrobienia, wyjaśnij to w obszarze dyskusji
Krok 5: Wniosek
Mam nadzieję, że ten artykuł będzie dla Ciebie przydatny. Przepraszam, jeśli pomyliłem się w tekście, ale angielski nie jest moim głównym językiem i mówię lepiej niż piszę.
Dzięki za przeczytanie wszystkiego.
Ciesz się tym.
Zalecana:
Komunikacja bezprzewodowa SmartHome: ekstremalne podstawy MQTT: 3 kroki
Komunikacja bezprzewodowa SmartHome: Ekstremalne podstawy MQTT: Podstawy MQTT: **Będę robił serię automatyki domowej, będę przechodził przez kroki, które podjąłem, aby dowiedzieć się wszystkiego, co zrobiłem w przyszłości. Ten Instructable jest podstawą konfiguracji MQTT do użytku w moich przyszłych Instructables. Jednak
Komunikacja bezprzewodowa LoRa 3Km do 8Km z tanim urządzeniem E32 (sx1278/sx1276) dla Arduino, Esp8266 lub Esp32: 15 kroków
LoRa 3Km do 8Km Bezprzewodowa komunikacja z niskokosztowym urządzeniem E32 (sx1278/sx1276) dla Arduino, Esp8266 lub Esp32: Tworzę bibliotekę do zarządzania EBYTE E32 opartą na urządzeniu LoRa serii Semtech, bardzo wydajne, proste i tanie urządzenie. Wersja 3Km tutaj, wersja 8Km tutaj Mogą pracować na dystansie od 3000m do 8000m i mają wiele funkcji i
Daleki zasięg, 1,8 km, bezprzewodowa komunikacja Arduino z Arduino z HC-12.: 6 kroków (ze zdjęciami)
Daleki zasięg, 1,8 km, komunikacja bezprzewodowa Arduino z Arduino z HC-12.: W tej instrukcji dowiesz się, jak komunikować się między Arduino na duże odległości do 1,8 km na świeżym powietrzu. HC-12 to bezprzewodowy port szeregowy moduł komunikacyjny, który jest bardzo przydatny, niezwykle wydajny i łatwy w użyciu. Najpierw opuścisz
Komunikacja bezprzewodowa za pomocą modułu nadawczo-odbiorczego NRF24L01 dla projektów opartych na Arduino: 5 kroków (ze zdjęciami)
Komunikacja bezprzewodowa przy użyciu modułu nadawczo-odbiorczego NRF24L01 dla projektów opartych na Arduino: To jest mój drugi samouczek dotyczący robotów i mikrokontrolerów. To naprawdę niesamowite widzieć swojego robota żywego i działającego zgodnie z oczekiwaniami i uwierz mi, że będzie fajniej, jeśli będziesz sterować swoim robotem lub innymi rzeczami bezprzewodowymi z szybkim i
Komunikacja bezprzewodowa przy użyciu tanich modułów RF 433 MHz i mikrokontrolerów Pic. Część 2: 4 kroki (ze zdjęciami)
Komunikacja bezprzewodowa przy użyciu tanich modułów RF 433 MHz i mikrokontrolerów Pic. Część 2: W pierwszej części tej instrukcji zademonstrowałem, jak zaprogramować PIC12F1822 za pomocą kompilatora MPLAB IDE i XC8, aby wysłać prosty ciąg bezprzewodowo za pomocą tanich modułów TX/RX 433 MHz. Moduł odbiornika został podłączony przez USB do UART TTL reklama kabla