สารบัญ:
- เสบียง
- ขั้นตอนที่ 1: 1. ตั้งค่า Atec608a
- ขั้นตอนที่ 2: 2. การออกแบบวงจร (Master และ Slave)
- ขั้นตอนที่ 3: 3. รหัส (Slave และ Master)
- ขั้นตอนที่ 4: 4. ก้าวต่อไป
- ขั้นตอนที่ 5: บทสรุป
วีดีโอ: การสื่อสารเข้ารหัสไร้สาย Arduino: 5 ขั้นตอน
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:03
สวัสดีทุกคน, ในบทความที่สองนี้ ฉันจะอธิบายวิธีใช้ชิป Atecc608a เพื่อรักษาความปลอดภัยให้กับการสื่อสารไร้สายของคุณ สำหรับสิ่งนี้ ฉันจะใช้ NRF24L01+ สำหรับส่วนไร้สายและ Arduino UNO
ไมโครชิป ATECC608A ได้รับการออกแบบโดย MicroChip และมีเครื่องมือรักษาความปลอดภัยมากมาย ตัวอย่างเช่น ชิปนี้สามารถเก็บ ECC Keys, AES Keys (สำหรับ AES 128) และ SHA2 Hash
บทความ: NRF24L01 + Arduino UNO + ATECC608A
ระหว่างการสื่อสารระหว่างสอง IoT Object การโจมตีหลายครั้งสามารถเกิดขึ้นได้: Man Of the Mild, Copy of information และอื่นๆ.. ดังนั้นความคิดของฉันจึงง่ายมาก:
- การใช้ข้อมูลที่เข้ารหัสระหว่างออบเจ็กต์ IoT สองรายการขึ้นไป
- วัตถุดิบราคาถูก
- สามารถทำงานร่วมกับ Arduino UNO
ในกรณีของฉัน ฉันใช้
- Atecc608a เพื่อจัดเก็บคีย์ AES ของฉัน และเพื่อเข้ารหัส/ถอดรหัสข้อมูลของฉัน
- Arduino Uno เป็นไมโครคอนโทรลเลอร์
- NRF24L01 เพื่อส่งข้อมูลของฉัน
คุณต้องทำตามขั้นตอนเหล่านั้นสำหรับโครงการนี้:
- ตั้งค่าชิป ATECC608A
- ทำวงจร (Master Node และ Slave Node)
- ส่วนรหัส
- ก้าวต่อไป !
สำหรับขั้นตอนแรก "ตั้งค่าชิป ATECC608A" ฉันได้เขียนบทความอื่นที่อธิบายแต่ละขั้นตอนตามลำดับ ลิงค์อยู่ที่นี่:
เริ่มเลย !
เสบียง
สำหรับโครงการนี้คุณต้องการ:
- 2 Arduino UNO หรือ Arduino NANO หรือ Arduino Mega
- สายบางๆ
- 2 Atec608a (ราคาแต่ละอันน้อยกว่า 0.60$)
- 2 NRF24L01+
- 2 ตัวเก็บประจุ (10 μF)
- เขียงหั่นขนม
ลิงก์ไปยังบทความของฉันที่อธิบายวิธีตั้งค่าชิป ATECC608A -> วิธีการตั้งค่า Atecc608a
ขั้นตอนที่ 1: 1. ตั้งค่า Atec608a
ฉันจะไม่ให้รายละเอียดทุกขั้นตอนในการติดตามเพื่อตั้งค่า ATECC608A เพราะฉันเขียนบทความฉบับเต็มซึ่งอธิบายทุกขั้นตอนที่ต้องทำ ในการตั้งค่า คุณต้องทำตาม "ขั้นตอนที่ 4" ของบทความนี้ชื่อ " 2. การกำหนดค่าชิป (Atecc608a)"
ลิงค์คือ: วิธีการตั้งค่า ATECC608A
นอกจากนี้ คุณต้องใส่การกำหนดค่าเดียวกันสำหรับ Atecc608a ฝั่งมาสเตอร์และฝั่งทาส มิฉะนั้น คุณจะไม่สามารถถอดรหัสข้อมูลของคุณได้
คำเตือน:
ในการตั้งค่าชิปนี้ คุณต้องปฏิบัติตามทุกขั้นตอนของบทความด้านบนตามลำดับ หากไม่มีขั้นตอนใดขั้นตอนหนึ่งหรือชิปไม่ล็อค คุณจะไม่สามารถทำโปรเจ็กต์นี้ได้
ส่วนที่เหลือ:
ขั้นตอนที่ต้องปฏิบัติตามนี้:
- สร้างเทมเพลตการกำหนดค่า
- เขียนเทมเพลตนี้ไปที่ชิป
- ล็อค Config Zone
- เขียนคีย์ AES ของคุณ (128 บิต) ลงในช่อง
- ล็อคโซนข้อมูล
ขั้นตอนที่ 2: 2. การออกแบบวงจร (Master และ Slave)
ในโครงการนี้ คุณจะมี Master Node และ Slave Node
โหนดหลักจะพิมพ์ข้อมูลที่ส่งโดยโหนดรองอย่างชัดเจน มันจะขอข้อมูลจากโหนดสเลฟทุก ๆ X ครั้ง
โหนดสเลฟจะฟัง "เครือข่าย" และเมื่อได้รับ "คำขอข้อมูล" โหนดจะสร้าง เข้ารหัส และส่งไปยังโหนดหลัก
สำหรับทั้งสองฝ่าย วงจรหลักและรองจะเหมือนกัน:
- หนึ่ง Arduino Nano
- ATECC608A. หนึ่งเครื่อง
- หนึ่ง NRF24L01
ฉันแนบวงจรกับขั้นตอนนี้ (cf ภาพด้านบน)
สำหรับ ATECC608A ถึง Arduino UNO นี่คือ 8 พิน soic ฉันเพิ่ม "มุมมองด้านบน" ด้านบน:
- ARDUINO 3.3V -> PIN 8 (Atecc608a)
- ARDUINO GND -> PIN 4 (Atecc608a)
- ARDUINO A4 (SDL) -> PIN 5 (Atecc608a)
- ARDUINO A5 (SCL) -> PIN 6 (Atecc608a)
สำหรับ NRF24L01 ถึง Arduino:
- ARDUINO 3.3V -> VCC (nrf24l01)
- ARDUINO GND -> GND (nrf24l01)
- ARDUINO 9 -> CE (nrf24l01)
- ARDUINO 10 -> CSN (nrf24l01)
- ARDUINO 11 -> MOSI (nrf24L01)
- ARDUINO 12 -> มิโซะ (nrf24l01)
- ARDUINO 13 -> SCK (nrf24l01)
- ARDUINO 3 -> IRQ (nrf24l01) -> เฉพาะโหนด Slave เท่านั้น ไม่ได้ใช้ในโหมดมาสเตอร์
เหตุใดจึงต้องใช้พิน IRQ ของ NRF24L01
พิน IRQ มีประโยชน์มาก พินนี้อนุญาตให้พูด (ต่ำ) เมื่อ NRF24L01 ได้รับแพ็กเก็ต ดังนั้นเราสามารถแนบ Interrupt กับพินนี้เพื่อปลุกโหนดสลาฟ
ขั้นตอนที่ 3: 3. รหัส (Slave และ Master)
โหนดทาส
ฉันใช้การประหยัดพลังงานสำหรับโหนดรองเพราะไม่จำเป็นต้องฟังตลอดเวลา
มันทำงานอย่างไร: โหนดทาสฟังและรอเพื่อรับ "แพ็คเก็ตปลุก" แพ็กเก็ตนี้ถูกส่งโดยโหนดมาสเตอร์เพื่อขอข้อมูลจากสเลฟ
ในกรณีของฉันฉันใช้อาร์เรย์สอง int:
// แพ็กเก็ตปลุก
const int wake_packet[2] = {20, 02};
หากโหนดของฉันได้รับแพ็กเก็ต
- มันตื่นขึ้น อ่านแพ็กเก็ตนี้ ถ้าแพ็กเก็ตเป็น "Wake UP"
- มันสร้างข้อมูล
- เข้ารหัสข้อมูล
- ส่งข้อมูลไปยังมาสเตอร์รอแพ็กเก็ต ACK
- นอน.
สำหรับการเข้ารหัส AES ฉันใช้คีย์ในช่องหมายเลข 9
นี่คือรหัสของฉันสำหรับโหนดทาส
#include "Arduino.h"#include "avr/sleep.h" #include "avr/wdt.h"
#รวม "SPI.h"
#รวม "nRF24L01.h" #รวม "RF24.h"
#รวม "Wire.h"
// ห้องสมุด ATECC608A
#include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h"
#define ID_NODE 255
#define AES_KEY (uint8_t)9
ATCAIfaceCfg cfg;
สถานะ ATCA_STATUS;
วิทยุ RF24 (9, 10);
const uint64_t masteraddresse = 0x1111111111;
const uint64_t slaveaddresse = 0x1111111100;
/**
* \brief ทำงานเมื่อมีการตั้งค่าอินเตอร์รัปต์ (IRQ LOW) * * */ void wakeUpIRQ() { while (radio.available()) { int data[32]; radio.read(&data, 32); ถ้า (data[0] == 20 && data[1] == 02) { float temp = 17.6; ลอย hum = 16.4;
ข้อมูล uint8_t[16];
uint8_t cypherdata[16];
// สร้างสตริงเพื่อตั้งค่าทั้งหมดของฉัน
// แต่ละค่าถูกคั่นด้วย "|" และ "$" หมายถึงจุดสิ้นสุดของข้อมูล // WARNING: ต้องมีความยาวน้อยกว่า 11 String tmp_str_data = String(ID_NODE) + "|" + สตริง (อุณหภูมิ 1) + "|" + สตริง(ฮัม 1) + "$"; //ขนาด 11 Serial.println("tmp_str_data: " + tmp_str_data);
tmp_str_data.getBytes (ข้อมูล ขนาด (ข้อมูล));
// เข้ารหัสข้อมูล
สถานะ ATCA_STATUS = aes_basic_encrypt(&cfg, data, sizeof(data), cypherdata, AES_KEY); ถ้า (สถานะ == ATCA_SUCCESS) { แรนด์ยาว = สุ่ม ((ยาว) 10000, (ยาว) 99999);
// สร้าง UUID ตามตัวเลขสามตัวแรก = ID node
สตริง uuid = สตริง (ID_NODE) + สตริง (แรนด์); // ขนาด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)); // หยุดฟัง radio.stopListening();
บูล rslt;
// ส่งข้อมูล rslt = radio.write(&data_to_send, sizeof(data_to_send)); // เริ่มฟัง radio.startListening(); if (rslt) {// สิ้นสุดและโหมดสลีป Serial.println (F ("เสร็จสิ้น")); } } } } }
การตั้งค่าเป็นโมฆะ ()
{ Serial.begin(9600);
// เริ่มตัวสร้างสำหรับห้องสมุด
cfg.iface_type = ATCA_I2C_IFACE; // ประเภทของการสื่อสาร -> โหมด I2C cfg.devtype = ATECC608A; // ประเภทของชิป cfg.atcai2c.slave_address = 0XC0; // ที่อยู่ I2C (ค่าเริ่มต้น) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // หน่วงเวลาปลุก (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(ที่อยู่หลัก);
radio.openReadingPipe(1, ที่อยู่ทาส); // แนบอินเทอร์รัปต์กับพิน 3 // แก้ไข 1 โดย O หากคุณต้องการอินเตอร์รัปต์กับพิน 2 // FALLING MODE = พินที่ LOW AttachInterrupt (1, wakeUpIRQ, FALLING); }
วงเป็นโมฆะ ()
{ // ไม่จำเป็น }
มาสเตอร์โหนด
โหนดหลักจะปลุกทุก 8 วินาทีเพื่อขอข้อมูลจากโหนดรอง
มันทำงานอย่างไร: โหนดหลักส่งแพ็กเก็ต "WakeUP" ไปยังสเลฟและหลังจากรอคำตอบของสเลฟพร้อมข้อมูล
ในกรณีของฉันฉันใช้อาร์เรย์สอง int:
// แพ็กเก็ตปลุก
const int wake_packet[2] = {20, 02};
หากโหนดรองส่งแพ็กเก็ต ACK หลังจากที่มาสเตอร์ส่งแพ็กเก็ต WakeUp:
- มาสเตอร์ตั้งค่าในโหมดฟังและรอการสื่อสาร
- ถ้าการสื่อสาร
- แยกไบต์แรก 8 ไบต์ ปล้น 3 ไบต์แรกของ 8 ไบต์ หากเป็นโหนด ID
- แยก 16 ไบต์ของ cypher
- ถอดรหัสข้อมูล
- พิมพ์ข้อมูลใน Serial
- โหมดสลีป
สำหรับการเข้ารหัส AES ฉันใช้คีย์ในช่องหมายเลข 9
นี่คือรหัสของฉันสำหรับโหนดหลัก
#รวม "Arduino.h"
#include "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // ATECC608A ไลบรารี #include "ATECCX08A_Arduino/cryptoauthlib.h" #include "AES BASIC/aes_basic.h" #define ID_NODE 255 #define AES_KEY (uint8_t)9 ATCAIfaceCfg cfg; สถานะ ATCA_STATUS; วิทยุ RF24 (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Wake UP แพ็กเก็ต const int wake_packet[2] = {20, 02}; // สุนัขเฝ้าบ้านขัดจังหวะ ISR (WDT_vect) { wdt_disable (); // ปิดการใช้งาน watchdog } โมฆะ sleepmode () { // ปิดการใช้งาน ADC ADCSRA = 0; // ล้างการตั้งค่าสถานะ "รีเซ็ต" ต่างๆ MCUSR = 0; // อนุญาตการเปลี่ยนแปลง ปิดใช้งานการรีเซ็ต WDTCSR = bit(WDCE) | บิต (WDE); // ตั้งค่าโหมดอินเตอร์รัปต์และช่วงเวลา WDTCSR = bit(WDIE) | บิต(WDP3) | บิต(WDP0); // ตั้งค่า WDIE และหน่วงเวลา 8 วินาที wdt_reset(); // รีเซ็ตสุนัขเฝ้าบ้าน set_sleep_mode (SLEEP_MODE_PWR_DOWN); ไม่มีอินเตอร์รัปต์ (); // ลำดับเวลาตาม sleep_enable(); // ปิดการเปิดใช้ Brown-out ในซอฟต์แวร์ MCUCR = bit(BODS) | บิต (BODSE); MCUCR = บิต (BODS); ขัดจังหวะ (); // รับประกันคำสั่งถัดไปที่ดำเนินการ sleep_cpu(); // ยกเลิกโหมดสลีปเพื่อเป็นการป้องกันไว้ก่อน sleep_disable(); } การตั้งค่าเป็นโมฆะ () { Serial.begin (9600); // เริ่มต้นตัวสร้างสำหรับไลบรารี cfg.iface_type = ATCA_I2C_IFACE; // ประเภทของการสื่อสาร -> โหมด I2C cfg.devtype = ATECC608A; // ประเภทของชิป cfg.atcai2c.slave_address = 0XC0; // ที่อยู่ I2C (ค่าเริ่มต้น) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // หน่วงเวลาปลุก (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(ที่อยู่ทาส); radio.openReadingPipe(1, ที่อยู่หลัก); } วงเป็นโมฆะ () { bool rslt; // ส่งข้อมูล rslt = radio.write(&wake_packet, sizeof(wake_packet)); if (rslt) { // เริ่มฟัง radio.startListening (); ในขณะที่ (radio.available ()) { uint8_t answer[32]; radio.read(&answer, sizeof(answer)); uint8_t node_id[3]; uint8_t cypher [16]; memcpy(node_id, คำตอบ, 3); memcpy(cypher, คำตอบ + 3, 16); ถ้า ((int) node_id == ID_NODE) { เอาต์พุต uint8_t [16]; สถานะ ATCA_STATUS = aes_basic_decrypt (&cfg, cypher, 16, เอาต์พุต, AES_KEY); ถ้า (สถานะ == ATCA_SUCCESS) { Serial.println ("ข้อมูลที่ถอดรหัส: "); สำหรับ (size_t i = 0; i < 16; i++) { Serial.print((char)output); } } } } } อื่น { Serial.println ("ไม่ได้รับ Ack สำหรับ Wakup Packet"); } // โหมดสลีป 8 วินาที sleepmode(); }
หากคุณมีคำถาม ฉันพร้อมที่จะตอบมัน
ขั้นตอนที่ 4: 4. ก้าวต่อไป
ตัวอย่างนี้เรียบง่ายเพื่อให้คุณสามารถปรับปรุงโครงการนี้ได้
การปรับปรุง:
- AES 128 เป็นพื้นฐานและคุณสามารถใช้อัลกอริทึมอื่นของ AES เป็น AES CBC ได้เพื่อความปลอดภัยยิ่งขึ้น
- เปลี่ยนโมดูลไร้สาย (NRF24L01 ถูกจำกัดโดยเพย์โหลด 23 ไบต์)
- …
หากคุณเห็นว่าต้องปรับปรุง ให้อธิบายในส่วนอภิปราย
ขั้นตอนที่ 5: บทสรุป
ฉันหวังว่าบทความนี้จะเป็นประโยชน์สำหรับคุณ ขออภัยถ้าฉันเขียนผิดในข้อความ แต่ภาษาอังกฤษไม่ใช่ภาษาหลักของฉัน และฉันพูดได้ดีกว่าที่ฉันเขียน
ขอบคุณสำหรับการอ่านทุกอย่าง
สนุกกับมัน.
แนะนำ:
การออกแบบเกมในการสะบัดใน 5 ขั้นตอน: 5 ขั้นตอน
การออกแบบเกมในการสะบัดใน 5 ขั้นตอน: การตวัดเป็นวิธีง่ายๆ ในการสร้างเกม โดยเฉพาะอย่างยิ่งเกมปริศนา นิยายภาพ หรือเกมผจญภัย
การตรวจจับใบหน้าบน Raspberry Pi 4B ใน 3 ขั้นตอน: 3 ขั้นตอน
การตรวจจับใบหน้าบน Raspberry Pi 4B ใน 3 ขั้นตอน: ในคำแนะนำนี้ เราจะทำการตรวจจับใบหน้าบน Raspberry Pi 4 ด้วย Shunya O/S โดยใช้ Shunyaface Library Shunyaface เป็นห้องสมุดจดจำใบหน้า/ตรวจจับใบหน้า โปรเจ็กต์นี้มีจุดมุ่งหมายเพื่อให้เกิดความเร็วในการตรวจจับและจดจำได้เร็วที่สุดด้วย
วิธีการติดตั้งปลั๊กอินใน WordPress ใน 3 ขั้นตอน: 3 ขั้นตอน
วิธีการติดตั้งปลั๊กอินใน WordPress ใน 3 ขั้นตอน: ในบทช่วยสอนนี้ ฉันจะแสดงขั้นตอนสำคัญในการติดตั้งปลั๊กอิน WordPress ให้กับเว็บไซต์ของคุณ โดยทั่วไป คุณสามารถติดตั้งปลั๊กอินได้สองวิธี วิธีแรกคือผ่าน ftp หรือผ่าน cpanel แต่ฉันจะไม่แสดงมันเพราะมันสอดคล้องกับ
การลอยแบบอะคูสติกด้วย Arduino Uno ทีละขั้นตอน (8 ขั้นตอน): 8 ขั้นตอน
การลอยแบบอะคูสติกด้วย Arduino Uno ทีละขั้นตอน (8 ขั้นตอน): ตัวแปลงสัญญาณเสียงล้ำเสียง L298N Dc ตัวเมียอะแดปเตอร์จ่ายไฟพร้อมขา DC ตัวผู้ Arduino UNOBreadboardวิธีการทำงาน: ก่อนอื่น คุณอัปโหลดรหัสไปยัง Arduino Uno (เป็นไมโครคอนโทรลเลอร์ที่ติดตั้งดิจิตอล และพอร์ตแอนะล็อกเพื่อแปลงรหัส (C++)
Arduino ที่ถูกที่สุด -- Arduino ที่เล็กที่สุด -- Arduino Pro Mini -- การเขียนโปรแกรม -- Arduino Neno: 6 ขั้นตอน (พร้อมรูปภาพ)
Arduino ที่ถูกที่สุด || Arduino ที่เล็กที่สุด || Arduino Pro Mini || การเขียนโปรแกรม || Arduino Neno:…………………………… โปรดสมัครสมาชิกช่อง YouTube ของฉันสำหรับวิดีโอเพิ่มเติม……. โปรเจ็กต์นี้เกี่ยวกับวิธีเชื่อมต่อ Arduino ที่เล็กที่สุดและถูกที่สุดเท่าที่เคยมีมา Arduino ที่เล็กที่สุดและถูกที่สุดคือ arduino pro mini คล้ายกับ Arduino