====== Essais de Communication en 433Mhz depuis un arduino vers un pc avec rtl_433 ======
{{ images:articles:diy:arduino:433_radiohead_aes128:img_20210223_213233.jpg?direct&150}}
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.
===== Émission depuis l'Arduino =====
J'ai utilisé le protocole [[http://www.airspayce.com/mikem/arduino/RadioHead/classRH__ASK.html#details|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 8-)
Pour le chiffrement j'ai utilisé l’implémentation d'[[https://rweather.github.io/arduinolibs/classAES128.html|AE128]] fournie par la lib [[https://github.com/OperatorFoundation/Crypto|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
#ifdef RH_HAVE_HARDWARE_SPI
#include // Not actually used but needed to compile
#endif
//import des libs crypto
#include
#include
// 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()
}
===== Réception et décodage coté PC =====
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
{{ images:articles:diy:arduino:433_radiohead_aes128:rtl_433-v.png?850 }}