Petit prototype permettant d’émettre des messages chiffrés (AES128) depuis un Arduino, sur 433Mz. La réception des messages s'effectue sur pc via RTL_433, le déchiffrement du message se fait via petit script python.
J'ai utilisé le protocole RadioHead ASK disponible pour Arduino et fonctionnant très bien avec les petit modules 433Mhz cheap que l'on trouve un peu partout. Ce protocole est nativement supporté par rtl_433 ce qui simplifie la vie
Pour le chiffrement j'ai utilisé l’implémentation d'AE128 fournie par la lib Crypto de Rhys Weatherley.
/** * Utilisation de RadioHead ASK pour transmettre des tableau d'octets chiffré * via AES128, à destination de rtl_433. * * http://www.airspayce.com/mikem/arduino/RadioHead/classRH__ASK.html#details * https://rweather.github.io/arduinolibs/classAES128.html */ // import des libs RadioHead pour l'émission radio #include <RH_ASK.h> #ifdef RH_HAVE_HARDWARE_SPI #include <SPI.h> // Not actually used but needed to compile #endif //import des libs crypto #include <Crypto.h> #include <AES.h> // initialisation du driver du module 433Mhz sur la pin D12 (defaut) RH_ASK driver; //TX to pin D12 // RH_ASK driver(2000, 4, 5, 0); // ESP8266 or ESP32: do not use pin 11 or 2 // RH_ASK driver(2000, 3, 4, 0); // ATTiny, RX on D3 (pin 2 on attiny85) TX on D4 (pin 3 on attiny85), AES128 cipher; // Instantiate an AES128 block ciphering unsigned char encryptkey[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,}; void setup() { #ifdef RH_HAVE_SERIAL Serial.begin(9600); // Debugging only #endif if (!driver.init()) #ifdef RH_HAVE_SERIAL Serial.println("init failed"); #else ; #endif // configuration de la clé de chiffrement cipher.setKey(encryptkey, sizeof(encryptkey)); // message à émettre uint8_t data[] = "Bumblebee"; //Chiffrement du message uint8_t buff[cipher.blockSize()]; cipher.encryptBlock(buff,data); //Émission du message driver.send(buff, cipher.blockSize()); // On envoie le message driver.waitPacketSent(); } void loop() { // ne fait rien // l'emission du message est dans le setup() }
Coté réception j'ai utilisé rtl_433 avec une clé TNT rtl_sdr basique.
La sortie (au format json pour me simplifier la vie) de rtl_433 est redirigé vers un script python utilisant la lib https://pypi.python.org/pypi/pycrypto[[PyCrypto pour déchiffrer et afficher les messages recus.
# https://techtutorialsx.com/2018/04/09/python-pycrypto-using-aes-128-in-ecb-mode/ from Crypto.Cipher import AES import fileinput import json key = bytes([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]) decipher = AES.new(key, AES.MODE_ECB) for line in fileinput.input(): try: data = json.loads(line) print('Payload') print(data.get('payload')) data_bytes = bytes(data.get('payload')) print('Decoded') print(decipher.decrypt(data_bytes).partition(b'\x00')[0].decode('utf-8')) except Exception as e: print(e) print('Err : ',json.loads(line))
Lancement de rtl_433 avec sortie json redirigée vers le script python :
rtl_433 -F json|python aes128.py