Სარჩევი:

უკაბელო დაშიფრული კომუნიკაცია Arduino: 5 ნაბიჯი
უკაბელო დაშიფრული კომუნიკაცია Arduino: 5 ნაბიჯი

ვიდეო: უკაბელო დაშიფრული კომუნიკაცია Arduino: 5 ნაბიჯი

ვიდეო: უკაბელო დაშიფრული კომუნიკაცია Arduino: 5 ნაბიჯი
ვიდეო: CS50 2015 - Week 10 2024, ნოემბერი
Anonim
უკაბელო დაშიფრული კომუნიკაცია Arduino
უკაბელო დაშიფრული კომუნიკაცია Arduino

Გამარჯობა ყველას, ამ მეორე სტატიაში მე აგიხსნით, თუ როგორ გამოიყენოთ ჩიპი Atecc608a თქვენი უკაბელო კომუნიკაციის უზრუნველსაყოფად. ამისათვის მე გამოვიყენებ NRF24L01+ უსადენო ნაწილისა და Arduino UNO– სთვის.

მიკრო ჩიპი ATECC608A შემუშავებულია MicroChip– ის მიერ და მიიღო უსაფრთხოების მრავალი ინსტრუმენტი. მაგალითად, ამ ჩიპს შეუძლია შეინახოს ECC Keys, AES Keys (AES 128 -ისთვის) და SHA2 Hash.

სტატია: NRF24L01 + Arduino UNO + ATECC608A

ორ IoT ობიექტს შორის კომუნიკაციის დროს შეიძლება განხორციელდეს მრავალი შეტევა: Man Of the mild, ინფორმაციის ასლი და სხვა.. ასე რომ, ჩემი იდეა ძალიან მარტივია:

  1. დაშიფრული მონაცემების გამოყენება ორ ან მეტ IoT ობიექტს შორის.
  2. დაბალი ღირებულების მარაგები
  3. შეუძლია მუშაობა Arduino UNO– სთან

ჩემს შემთხვევაში, მე ვიყენებ

  • Atecc608a ჩემი AES გასაღების შესანახად და ჩემი მონაცემების დაშიფვრის/გაშიფვრის მიზნით.
  • Arduino Uno როგორც მიკროკონტროლერი
  • NRF24L01 ჩემი მონაცემების გასაგზავნად

თქვენ უნდა შეასრულოთ ეს ნაბიჯები ამ პროექტისთვის:

  1. დააყენეთ ჩიპი ATECC608A
  2. გააკეთეთ წრე (სამაგისტრო კვანძი და მონა კვანძი)
  3. კოდის ნაწილი
  4. Გზის გაგრძელება !

პირველი ნაბიჯებისთვის "ჩიპის დაყენება ATECC608A", მე დავწერე სხვა სტატია, რომელიც განმარტავს თითოეულ ნაბიჯს თანმიმდევრობით. ბმული აქ არის:

ახლა დაიწყე!

მარაგები

ამ პროექტისთვის გჭირდებათ:

  • 2 Arduino UNO ან Arduino NANO ან Arduino Mega
  • რაღაც მავთული
  • 2 Atecc608a (თითოეული ღირს 0.60 $ -ზე ნაკლები)
  • 2 NRF24L01+
  • 2 კონდენსატორი (10 μF)
  • პურის დაფები

ბმული ჩემს სტატიასთან, რომელიც განმარტავს, თუ როგორ შეიქმნა ჩიპი ATECC608A -> როგორ დავაყენოთ Atecc608a

ნაბიჯი 1: 1. დააყენეთ Atecc608a

1. დააყენეთ Atecc608a
1. დააყენეთ Atecc608a
1. დააყენეთ Atecc608a
1. დააყენეთ Atecc608a

მე არ დავაკონკრეტებ თითოეულ ნაბიჯს ATECC608A– ს დასაყენებლად, რადგან დავწერე სრული სტატია, რომელიც განმარტავს ამის გაკეთების ყველა ნაბიჯს. მისი დასაყენებლად, თქვენ უნდა დაიცვას ამ სტატიის "ნაბიჯი 4" სახელწოდებით "2. ჩიპის კონფიგურაცია (Atecc608a)"

ბმული არის: როგორ დავაყენოთ ATECC608A

ასევე, თქვენ უნდა დააყენოთ იგივე კონფიგურაცია Atecc608a, სამაგისტრო და მონა მხარეებისთვის, წინააღმდეგ შემთხვევაში თქვენ ვერ შეძლებთ თქვენი მონაცემების გაშიფვრას

გაფრთხილება:

ამ ჩიპის დასაყენებლად, თქვენ უნდა დაიცვას ზემოთ მოცემული სტატიის ყველა ნაბიჯი თანმიმდევრობით. თუ ერთი ნაბიჯი აკლია ან ჩიპი არ არის ჩაკეტილი, თქვენ ვერ შეძლებთ ამ პროექტის განხორციელებას

დანარჩენი:

ნაბიჯი, რომელიც უნდა დაიცვას ამისათვის:

  • შექმენით კონფიგურაციის შაბლონი
  • ჩაწერეთ ეს შაბლონი ჩიპზე
  • კონფიგურაციის ზონის ჩაკეტვა
  • ჩაწერეთ თქვენი AES გასაღები (128 ბიტი) სლოტში
  • ჩაკეტეთ მონაცემთა ზონა

ნაბიჯი 2: 2. სქემის დიზაინი (ოსტატი და მონა)

2. სქემის დიზაინი (ოსტატი და მონა)
2. სქემის დიზაინი (ოსტატი და მონა)
2. სქემის დიზაინი (ოსტატი და მონა)
2. სქემის დიზაინი (ოსტატი და მონა)

ამ პროექტში გექნებათ სამაგისტრო კვანძი და მონა კვანძი.

სამაგისტრო კვანძი ნათლად დაბეჭდავს მონა კვანძის მიერ გაგზავნილ მონაცემებს. ის მოითხოვს მონაცემებს მონა კვანძიდან ყოველ X დროს.

მონა კვანძი მოუსმენს "ქსელს" და როდესაც მიიღებს "მოთხოვნის მონაცემებს", გამოიმუშავებს მას, დაშიფვრავს და გაუგზავნის მას ძირითად კვანძს.

ორივე მხარისთვის, სამაგისტრო და მონა სქემა იგივეა:

  • ერთი არდუინო ნანო
  • ერთი ATECC608A
  • ერთი NRF24L01

მე დავამატე წრე ამ ნაბიჯზე (იხ. სურათი ზემოთ).

ATECC608A– ს Arduino UNO– სთვის, ეს არის soic 8 პინი. მე დავამატე "ზედა ხედი" ზემოთ:

  • 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 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) -> მხოლოდ მონა კვანძისათვის, არ გამოიყენება სამაგისტრო რეჟიმში

რატომ გამოვიყენოთ NRF24L01 IRQ პინი

IRQ პინი ძალიან სასარგებლოა, ეს პინი იძლევა საშუალებას ვთქვათ (LOW) როდესაც პაკეტი მიიღება NRF24L01- ით, ასე რომ ჩვენ შეგვიძლია დავამატოთ Interrupt ამ პინს, რომ გააღვიძოს მონა კვანძი.

ნაბიჯი 3: 3. კოდი (მონა და ოსტატი)

3. კოდი (მონა და ოსტატი)
3. კოდი (მონა და ოსტატი)

მონა კვანძი

მე ვიყენებ ენერგიის დაზოგვას მონა კვანძისათვის, რადგან მას არ სჭირდება ყველა დროის მოსმენა.

როგორ მუშაობს: მონა კვანძი უსმენს და ელოდება "Wake UP პაკეტის" მიღებას. ეს პაკეტი იგზავნება სამაგისტრო კვანძის მიერ მონას მონაცემების სათხოვნელად.

ჩემს შემთხვევაში მე ვიყენებ მასივს ორი int:

// Wake UP პაკეტი

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

თუ ჩემი კვანძი მიიღებს პაკეტს,

  1. გაიღვიძე, წაიკითხე ეს პაკეტი, თუ პაკეტი არის "გაიღვიძე",
  2. ის გენერირებს მონაცემებს,
  3. მონაცემების დაშიფვრა,
  4. გაგზავნეთ მონაცემები ოსტატს, დაელოდეთ ACK პაკეტს,
  5. ძილი.

AES დაშიფვრისთვის მე ვიყენებ გასაღებს სლოტ ნომერში 9.

ეს არის ჩემი მონა მონა კოდისთვის

#მოიცავს "Arduino.h" #მოიცავს "avr/sleep.h" #მოიცავს "avr/wdt.h"

#მოიცავს "SPI.h"

#მოიცავს "nRF24L01.h" #მოიცავს "RF24.h"

#მოიცავს "Wire.h"

// ATECC608A ბიბლიოთეკა

#მოიცავს "ATECCX08A_Arduino/cryptoauthlib.h" #მოიცავს "AES BASIC/aes_basic.h"

#განსაზღვრეთ ID_NODE 255

#განსაზღვრეთ AES_KEY (uint8_t) 9

ATCAIfaceCfg cfg;

ATCA_STATUS სტატუსი;

RF24 რადიო (9, 10);

const uint64_t masteraddresse = 0x1111111111;

const uint64_t slaveaddresse = 0x1111111100;

/**

* / მოკლე ფუნქცია შესრულებულია შეწყვეტის დაყენებისას (IRQ LOW) * * */ void wakeUpIRQ () {while (radio.available ()) {int data [32]; radio.read (& მონაცემები, 32); if (მონაცემები [0] == 20 && მონაცემები [1] == 02) {float temp = 17.6; float hum = 16.4;

uint8_t მონაცემები [16];

uint8_t cypherdata [16];

// ავაშენოთ სიმებიანი, რომ დავაყენო მთელი ჩემი მნიშვნელობა

// თითოეული მნიშვნელობა გამოყოფილია "|" და "$" ნიშნავს მონაცემების დასასრულს // გაფრთხილება: უნდა იყოს 11 -ზე ნაკლები სიგრძის სიმებიანი tmp_str_data = სიმებიანი (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 კვანძის საფუძველზე

სიმებიანი uuid = სიმებიანი (ID_NODE) + სიმებიანი (რანდი); // ზომა 8

uint8_t tmp_uuid [8];

uint8_t მონაცემები_ გასაგზავნად [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)); // შეწყვიტე რადიოს მოსმენა. StopListening ();

bool rslt;

// მონაცემების გაგზავნა rslt = radio.write (& data_to_send, sizeof (data_to_send)); // რადიოს მოსმენა დაწყება. 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.setDataRate (RF24_250KBPS); radio.maskIRQ (1, 1, 0); radio.enableAckPayload (); radio.setRetries (5, 5);

radio.openWritingPipe (masteraddresse);

radio.openReadingPipe (1, slaveaddresse); // მიამაგრეთ შეწყვეტა პინზე 3 // შეცვალეთ 1 ო, თუ გინდათ შეწყვეტა ქინძისთავზე 2 // FALLING MODE = მიამაგრეთ LOW attachInterrupt (1, wakeUpIRQ, FALLING); }

ბათილი მარყუჟი ()

{ // Არ არის საჭიროება }

სამაგისტრო კვანძი

სამაგისტრო კვანძი იღვიძებს ყოველ 8 წამში მონა მონაცემ კვანძის მონაცემების სათხოვნელად

როგორ მუშაობს: სამაგისტრო კვანძი აგზავნის "WakeUP" პაკეტს მონას და ელოდება მას შემდეგ მონას პასუხობს მონაცემებით.

ჩემს შემთხვევაში მე ვიყენებ მასივს ორი int:

// Wake UP პაკეტი

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

თუ მონა კვანძი აგზავნის ACK პაკეტს მასტერის მიერ WakeUp პაკეტის გაგზავნის შემდეგ:

  1. სამაგისტრო შეიქმნა მოსმენის რეჟიმში და დაელოდეთ კომუნიკაციას
  2. თუ კომუნიკაცია
  3. ამონაწერი 8 პირველი ბაიტი, ძარცვა სამი პირველი ბაიტი 8 ბაიტიდან, თუ ეს არის ID კვანძი
  4. ამოიღეთ ციფერის 16 ბაიტი
  5. მონაცემების გაშიფვრა
  6. დაბეჭდეთ მონაცემები სერიალში
  7. Ძილის რეჟიმი

AES დაშიფვრისთვის მე ვიყენებ გასაღებს სლოტ ნომერში 9.

ეს არის ჩემი კოდი სამაგისტრო კვანძისათვის

#მოიცავს "Arduino.h"

#მოიცავს "avr/sleep.h" #მოიცავს "avr/wdt.h" #მოიცავს "SPI.h" #მოიცავს "nRF24L01.h" #მოიცავს "RF24.h" #მოიცავს "Wire.h" // ATECC608A ბიბლიოთეკა #მოიცავს "ATECCX08A_Arduino/cryptoauthlib.h" #მოიცავს "AES BASIC/aes_basic.h" #განსაზღვრეთ ID_NODE 255 #განსაზღვრეთ AES_KEY (uint8_t) 9 ATCAIfaceCfg cfg; ATCA_STATUS სტატუსი; RF24 რადიო (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Wake UP packet const int wake_packet [2] = {20, 02}; // მეთვალყურე შეწყვეტს ISR (WDT_vect) {wdt_disable (); // გამორთეთ გუშაგი} void sleepmode () {// გამორთეთ ADC ADCSRA = 0; // სხვადასხვა "გადატვირთვის" დროშების გასუფთავება MCUSR = 0; // ცვლილებების დაშვება, გამორთვა გადატვირთვის WDTCSR = ბიტი (WDCE) | ბიტი (WDE); // დააყენეთ შეწყვეტის რეჟიმი და ინტერვალი WDTCSR = ბიტი (WDIE) | ბიტი (WDP3) | ბიტი (WDP0); // დააყენეთ WDIE და 8 წამი გადაიდო wdt_reset (); // გადააყენეთ მეთვალყურე set_sleep_mode (SLEEP_MODE_PWR_DOWN); noIterrupts (); // დროული თანმიმდევრობა მიჰყვება sleep_enable (); // გამორთეთ brown ‐ out ჩართვა პროგრამულ უზრუნველყოფაში MCUCR = bit (BODS) | ბიტი (BODSE); MCUCR = ბიტი (BODS); წყვეტს (); // გარანტიას აძლევს მომდევნო ინსტრუქციას შესრულებული sleep_cpu (); // გააუქმოს ძილი სიფრთხილით sleep_disable (); } void setup () {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.setDataRate (RF24_250KBPS); radio.maskIRQ (1, 1, 0); radio.enableAckPayload (); radio.setRetries (5, 5); radio.openWritingPipe (slaveaddresse); radio.openReadingPipe (1, masteraddresse); } void loop () {bool rslt; // მონაცემების გაგზავნა rslt = radio.write (& wake_packet, sizeof (wake_packet)); if (rslt) {// დაიწყეთ radio.startListening () მოსმენა; ხოლო (radio.available ()) {uint8_t პასუხი [32]; radio.read (& პასუხი, ზომა (პასუხი)); uint8_t node_id [3]; uint8_t cypher [16]; memcpy (node_id, პასუხი, 3); memcpy (cypher, პასუხი + 3, 16); if ((int) node_id == ID_NODE) {uint8_t გამომავალი [16]; ATCA_STATUS სტატუსი = aes_basic_decrypt (& cfg, cypher, 16, output, AES_KEY); if (სტატუსი == ATCA_SUCCESS) {Serial.println ("გაშიფრული მონაცემები:"); for (size_t i = 0; i <16; i ++) {Serial.print ((char) გამომავალი ); }}}}} სხვა {Serial.println ("Ack not get for Wakup Packet"); } // ძილის რეჟიმი 8 წამიანი ძილის რეჟიმი (); }

თუ თქვენ გაქვთ რაიმე შეკითხვა, მე აქ ვარ, რომ გიპასუხოთ

ნაბიჯი 4: 4. წადი უფრო შორს

ეს მაგალითი მარტივია, ასე რომ თქვენ შეგიძლიათ გააუმჯობესოთ ეს პროექტი

გაუმჯობესებები:

  • AES 128 არის ძირითადი და თქვენ შეგიძლიათ გამოიყენოთ AES– ის სხვა ალგორითმი, როგორც AES CBC, რომ იყოთ უფრო უსაფრთხო.
  • შეცვალეთ უკაბელო მოდული (NRF24L01 შემოიფარგლება 23 ბაიტიანი დატვირთვით)

თუ ხედავთ გასაუმჯობესებლად, აუხსენით ის დისკუსიის არეალში

ნაბიჯი 5: დასკვნა

ვიმედოვნებ, რომ ეს სტატია თქვენთვის სასარგებლო იქნება. უკაცრავად, თუ მე დავუშვი შეცდომა ჩემს ტექსტში, მაგრამ ინგლისური არ არის ჩემი მთავარი ენა და მე უკეთ ვსაუბრობ ვიდრე ვწერ.

მადლობა რომ კითხულობ ყველაფერს.

Ისიამოვნე.

გირჩევთ: