İçindekiler:

Kablosuz Şifreli İletişim Arduino: 5 Adım
Kablosuz Şifreli İletişim Arduino: 5 Adım

Video: Kablosuz Şifreli İletişim Arduino: 5 Adım

Video: Kablosuz Şifreli İletişim Arduino: 5 Adım
Video: Arduino 433 mhz RF Alıcı (Receiver) Verici (Trasmitter) Modül Kullanımı | Virtual Wire 2024, Kasım
Anonim
Kablosuz Şifreli İletişim Arduino
Kablosuz Şifreli İletişim Arduino

Herkese merhaba, Bu ikinci yazımda size kablosuz iletişiminizi güvence altına almak için Atecc608a çipini nasıl kullanacağınızı anlatacağım. Bunun için Kablosuz kısım için NRF24L01+ ve Arduino UNO'yu kullanacağım.

Mikro çip ATECC608A, MicroChip tarafından tasarlanmıştır ve birden fazla güvenlik aracına sahiptir. Örneğin, bu çip ECC Anahtarlarını, AES Anahtarlarını (AES 128 için) ve SHA2 Hash'ini depolayabilir.

Makale: NRF24L01 + Arduino UNO + ATECC608A

İki IoT Nesnesi arasındaki bir iletişim sırasında birden fazla saldırı olabilir: Man Of the hafif, Bilginin kopyası ve daha fazlası.. Yani benim fikrim çok basit:

  1. İki veya daha fazla IoT nesnesi arasında şifrelenmiş verilerin kullanılması.
  2. Düşük maliyetli sarf malzemeleri
  3. Arduino UNO ile çalışabilir

Benim durumumda kullanıyorum

  • AES Anahtarımı saklamak ve verilerimi şifrelemek/şifresini çözmek için Atecc608a.
  • Mikrodenetleyici olarak Arduino Uno
  • Verilerimi göndermek için NRF24L01

Bu proje için şu adımları izlemeniz gerekiyor:

  1. ATECC608A çipini kurun
  2. Devreyi yapın (Ana Düğüm ve Köle Düğüm)
  3. Kod parçası
  4. Daha İleri Git!

"ATECC608A çipini kurun" ilk adımları için, her adımı sırayla açıklayan başka bir makale yazdım. Bağlantı burada:

Şimdi başla !

Gereçler

Bu proje için ihtiyacınız olan:

  • 2 Arduino UNO veya Arduino NANO veya Arduino Mega
  • biraz tel
  • 2 Atecc608a (her birinin maliyeti 0,60$'dan az)
  • 2 NRF24L01+
  • 2 kapasitör (10 μF)
  • Breadboard'lar

ATECC608A çipinin nasıl kurulduğunu açıklayan makaleme bağlantı -> Atecc608a nasıl kurulur

Adım 1: 1. Atecc608a'yı kurun

1. Atecc608a'yı kurun
1. Atecc608a'yı kurun
1. Atecc608a'yı kurun
1. Atecc608a'yı kurun

Bir ATECC608A kurmak için izlenecek her adımı detaylandırmayacağım çünkü bunu yapmak için her adımı açıklayan tam bir makale yazdım. Bunu kurmak için " 2. Çip Yapılandırması (Atecc608a) " adlı bu makalenin "4. Adımını" izlemeniz gerekir.

Bağlantı: ATECC608A nasıl kurulur

Ayrıca, Atecc608a, ana taraf ve bağımlı taraf için aynı konfigürasyonu yapmanız gerekir, aksi takdirde verilerinizin şifresini çözemezsiniz

Uyarı:

Bu çipi kurmak için yukarıdaki yazının her adımını sırasıyla takip etmeniz gerekiyor. Bir adım eksikse veya çip kilitli değilse, bu projeyi yapamazsınız

kalan:

Bunun için izlenecek adım:

  • Bir yapılandırma şablonu oluşturun
  • Bu şablonu çipe yazın
  • Yapılandırma Alanını Kilitle
  • AES Anahtarınızı (128 Bit) bir yuvaya yazın
  • Veri Bölgesini Kilitle

Adım 2: 2. Devrenin Tasarımı (Master ve Slave)

2. Devre Tasarımı (Master ve Slave)
2. Devre Tasarımı (Master ve Slave)
2. Devre Tasarımı (Master ve Slave)
2. Devre Tasarımı (Master ve Slave)

Bu projede, bir Ana Düğüm ve bir Köle Düğümünüz olacak.

Ana düğüm, bağımlı düğüm tarafından gönderilen verileri net bir şekilde yazdıracaktır. Her X seferinde köle düğümden veri isteyecektir.

Köle düğüm "ağ"ı dinler ve bir "Talep verisi" aldığında onu oluşturur, şifreler ve ana düğüme gönderir.

Her iki taraf, master ve slave için devre aynıdır:

  • Bir arduino Nano
  • Bir ATECC608A
  • Bir NRF24L01

Devreyi bu adıma ekledim (yukarıdaki resme bakın).

Arduino UNO'ya ATECC608A için, bu bir soic 8 pinidir. Yukarıya "üstten görünümü" ekledim:

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

Arduino'ya NRF24L01 için:

  • 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) -> yalnızca Slave düğümü için, Master modunda kullanılmaz

NRF24L01'in IRQ pinini neden kullanmalısınız?

IRQ pimi çok kullanışlıdır, bu pim NRF24L01 tarafından bir paket alındığında (DÜŞÜK) dememizi sağlar, böylece bağımlı düğümü uyandırmak için bu pime bir Kesinti ekleyebiliriz.

Adım 3: 3. Kod (Slave ve Master)

3. Kod (Slave ve Master)
3. Kod (Slave ve Master)

Köle Düğümü

Köle Düğüm için güç tasarrufunu kullanıyorum çünkü her zaman dinlemesi gerekmiyor.

Nasıl çalışır: bağımlı düğüm dinler ve bir "Uyandırma paketi" almayı bekler. Bu paket Master düğüm tarafından köleden veri istemek için gönderilir.

Benim durumumda iki int dizisi kullanıyorum:

// Uyandırma paketi

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

Düğüm bir paket alırsa,

  1. uyan, bu paketi oku, eğer paket bir "Uyandır" ise,
  2. verileri üretir,
  3. verileri şifrelemek,
  4. verileri master'a gönderin, bir ACK paketi bekleyin,
  5. uyku.

AES Şifrelemesi için 9 numaralı yuvada bir anahtar kullanıyorum.

Bu benim Slave düğümü için kodum

#include "Arduino.h"#include "avr/sleep.h" #include "avr/wdt.h"

#include "SPI.h"

#include "nRF24L01.h" #include "RF24.h"

#include "Wire.h"

// ATECC608A kitaplığı

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

RF24 telsiz(9, 10);

const uint64_t ana adres = 0x111111111;

const uint64_t köleadresi = 0x1111111100;

/**

* \brief Kesme ayarlandığında çalıştırılan işlev (IRQ LOW) * * */ void wakeUpIRQ() { while (radio.available()) { int data[32]; radio.read(&veri, 32); if (veri[0] == 20 && veri[1] == 02) { kayan nokta sıcaklığı = 17.6; yüzer uğultu = 16.4;

uint8_t veri[16];

uint8_t şifreleme verileri[16];

// Tüm Değerimi ayarlamak için bir Dize oluşturun

// Her değer bir "|" ile ayrılır ve "$" verinin sonu anlamına gelir // UYARI: 11 uzunluktan az olmalıdır String tmp_str_data = String(ID_NODE) + "|" + String(temp, 1) + "|" + String(vızıldama, 1) + "$"; //11 boyutu Serial.println("tmp_str_data: " + tmp_str_data);

tmp_str_data.getBytes(veri, sizeof(veri));

// Verileri şifrele

ATCA_STATUS durumu = aes_basic_encrypt(&cfg, data, sizeof(data), cypherdata, AES_KEY); if (durum == ATCA_SUCCESS) { uzun rand = rastgele((uzun)10000, (uzun)99999);

// ilk üç sayıya dayalı bir UUID oluştur = ID düğümü

String uuid = String(ID_NODE) + String(rand); // 8 boyutu

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)); // radyo dinlemeyi bırak.stopListening();

bool rslt;

// Veri Gönder rslt = radio.write(&data_to_send, sizeof(data_to_send)); // Dinlemeye Başla radio.startListening(); if (rslt) { // Bitiş ve uyku modu Serial.println(F("Bitti")); } } } } }

geçersiz kurulum()

{ Serial.başlangıç(9600);

// Kitaplık için kurucuyu başlat

cfg.iface_type = ATCA_I2C_IFACE; // İletişim türü -> I2C modu cfg.devtype = ATECC608A; // Çip türü cfg.atcai2c.slave_address = 0XC0; // I2C adresi (varsayılan değer) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Uyanma gecikmesi (1500 ms) cfg.rx_retries = 20;

radyo.begin();

radio.setDataRate(RF24_250KBPS); radio.maskIRQ(1, 1, 0); radio.enableAckPayload(); radio.setRetries(5, 5);

radio.openWritingPipe(masteraddresse);

radio.openReadingPipe(1, köleadresi); // Kesintiyi pim 3'e ekleyin // Kesintiyi pim 2'ye istiyorsanız, 1'i O ile değiştirin // FALLING MODE = LOW AttachInterrupt(1, wakeUpIRQ, FALLING); }

boşluk döngüsü()

{ // Gerek yok }

Ana Düğüm

Ana düğüm, bağımlı düğümden veri istemek için her 8 saniyede bir uyanır

Nasıl Çalışır: Ana düğüm, köleye bir "Uyandırma" paketi gönderir ve ardından kölenin verilerle yanıtını bekler.

Benim durumumda iki int dizisi kullanıyorum:

// Uyandırma paketi

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

Ana düğüm bir Uyandırma paketi gönderdikten sonra bağımlı düğüm bir ACK paketi gönderirse:

  1. Dinleme modunda ana kurulum ve bir iletişim bekleyin
  2. eğer iletişim
  3. İlk 8 baytı ayıklayın, bu kimlik düğümüyse, 8 baytın ilk üç baytını yağmalayın
  4. 16 bayt şifreyi ayıklayın
  5. Verilerin şifresini çöz
  6. Verileri Seri olarak yazdırın
  7. Uyku modu

AES Şifrelemesi için 9 numaralı yuvada bir anahtar kullanıyorum.

Bu, Ana düğüm için kodum

#include "Arduino.h"

#include "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // ATECC608A kitaplığı #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 durumu; RF24 telsiz(9, 10); const uint64_t ana adres = 0x111111111; const uint64_t köleadresi = 0x1111111100; // Uyandırma paketi const int wake_packet[2] = {20, 02}; // watchdog interrupt ISR(WDT_vect) { wdt_disable(); // watchdog'u devre dışı bırak } void sleepmode() { // ADC'yi devre dışı bırak ADCSRA = 0; // çeşitli "reset" bayraklarını temizle MCUSR = 0; // değişikliklere izin ver, sıfırlamayı devre dışı bırak WDTCSR = bit(WDCE) | bit(WDE); // kesme modunu ve bir aralığı ayarla WDTCSR = bit(WDIE) | bit(WDP3) | bit(WDP0); // WDIE'yi ayarla ve 8 saniye gecikme wdt_reset(); // watchdog set_sleep_mode(SLEEP_MODE_PWR_DOWN); noInterrupts(); // zamanlamalı dizi, sleep_enable(); // MCUCR yazılımında kararmayı etkinleştirmeyi kapatın = bit(BODS) | bit(BODSE); MCUCR = bit(BODS); kesintiler(); // bir sonraki komutun yürütülmesini garanti eder sleep_cpu(); // önlem olarak uykuyu iptal et sleep_disable(); } geçersiz kurulum() { Serial.begin(9600); // cfg.iface_type = ATCA_I2C_IFACE kitaplığı için kurucuyu başlatın; // İletişim türü -> I2C modu cfg.devtype = ATECC608A; // Çip türü cfg.atcai2c.slave_address = 0XC0; // I2C adresi (varsayılan değer) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Uyanma gecikmesi (1500 ms) cfg.rx_retries = 20; radyo.begin(); radio.setDataRate(RF24_250KBPS); radio.maskIRQ(1, 1, 0); radio.enableAckPayload(); radio.setRetries(5, 5); radio.openWritingPipe(slaveaddresse); radio.openReadingPipe(1, anaadres); } geçersiz döngü() { bool rslt; // Veri Gönder rslt = radio.write(&wake_packet, sizeof(wake_packet)); if (rslt) { // Dinlemeye Başla radio.startListening(); while (radio.available()) { uint8_t cevap[32]; radio.read(&cevap, sizeof(cevap)); uint8_t düğüm_kimliği[3]; uint8_t şifre[16]; memcpy(node_id, cevap, 3); memcpy(şifre, cevap + 3, 16); if ((int)node_id == ID_NODE) { uint8_t çıktı[16]; ATCA_STATUS durumu = aes_basic_decrypt(&cfg, cypher, 16, output, AES_KEY); if (durum == ATCA_SUCCESS) { Serial.println("Şifrelenmiş Veri: "); for (size_t i = 0; i < 16; i++) { Serial.print((char)output); } } } } } else{ Serial.println("Uyandırma Paketi için alınmadı"); } // Uyku modu 8 saniye uyku modu(); }

Bir sorunuz varsa, cevaplamak için buradayım

Adım 4: 4. Daha İleri Gidin

Bu örnek basittir, böylece bu projeyi geliştirebilirsiniz

İyileştirmeler:

  • AES 128 temeldir ve daha güvenli olması için AES CBC olarak başka bir AES algoritması kullanabilirsiniz.
  • Kablosuz modülü değiştirin (NRF24L01, 23 Baytlık bir yük ile sınırlıdır)

Yapılması gereken bir gelişme görüyorsanız, bunu tartışma alanında açıklayın.

Adım 5: Sonuç

Umarım bu makale sizin için faydalı olacaktır. Yazımda hata yaptıysam özür dilerim ama İngilizce ana dilim değil ve yazdığımdan daha iyi konuşuyorum.

Her şeyi okuduğunuz için teşekkürler.

Tadını çıkar.

Önerilen: