Skip to main content
Bumped by Community user
Bumped by Community user
added 1638 characters in body
Source Link

*EDIT

I thought if it helps I could provide a bit more context around the transmission stages that the message goes through:

After the initial data string is constructed from the temperature and humidity sensor eg "55.55,24.99,0001" that 16 byte message is added to a 32 byte char array and encrypted using the aes128_enc_single method. The encrypted message is then base63 encoded The encrypted char array is then combined with an extra unencrypted character "Ʊ" (which I thought I could use to crudely validate the message) and sent via the radiohead ask send method:

driver.send(strcat( (uint8_t *)encodedString, endChar ), 33);

On the pyhton/reciever end I run a sub process rtl_433 -f 433720000 -F json

and listen for the output line by line. A example of the output of the rtl_433 command would look something like this: {"time": "2019-03-05 00:00:00", "model": "RadioHead ASK", "len": 33, "to": 255, "from": 255, "id": 0, "flags": 0, "payload": [111, 110, 109, 57, 120, 86, 52, 79, 121, 78, 71, 52, 48, 122, 117, 88, 67, 52, 77, 118, 85, 81, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65], "mic": "CRC"}

rtl_433 converts the message into an array of ASCII or Unicode characters.

I have then tried to convert the characters in the recieved array back into standard characters: payloadstring += chr(payload[a]) added padding to the message: payloadstring += "AAAAAAAAAA=" then base64 decoded the result: encrypted = base64.b64decode(payloadstring) and then finally decrypt that: decrypted = decrypt(encrypted)

Hopefully that info might be helpful in flagging up where I have gone wrong.

*EDIT

I thought if it helps I could provide a bit more context around the transmission stages that the message goes through:

After the initial data string is constructed from the temperature and humidity sensor eg "55.55,24.99,0001" that 16 byte message is added to a 32 byte char array and encrypted using the aes128_enc_single method. The encrypted message is then base63 encoded The encrypted char array is then combined with an extra unencrypted character "Ʊ" (which I thought I could use to crudely validate the message) and sent via the radiohead ask send method:

driver.send(strcat( (uint8_t *)encodedString, endChar ), 33);

On the pyhton/reciever end I run a sub process rtl_433 -f 433720000 -F json

and listen for the output line by line. A example of the output of the rtl_433 command would look something like this: {"time": "2019-03-05 00:00:00", "model": "RadioHead ASK", "len": 33, "to": 255, "from": 255, "id": 0, "flags": 0, "payload": [111, 110, 109, 57, 120, 86, 52, 79, 121, 78, 71, 52, 48, 122, 117, 88, 67, 52, 77, 118, 85, 81, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65], "mic": "CRC"}

rtl_433 converts the message into an array of ASCII or Unicode characters.

I have then tried to convert the characters in the recieved array back into standard characters: payloadstring += chr(payload[a]) added padding to the message: payloadstring += "AAAAAAAAAA=" then base64 decoded the result: encrypted = base64.b64decode(payloadstring) and then finally decrypt that: decrypted = decrypt(encrypted)

Hopefully that info might be helpful in flagging up where I have gone wrong.

Source Link

Help decrypting AES string from arduino rf module in python

Please excuse any glaring errors in my code, I'm new to both C and python.

I'm trying to send an encrypted message from my arduino uno via a DHT22 sensor and an rf module using the radiohead ask and AESlib libraries to a raspberry pi with a usb RTL-SDR using the rtl_433 library and a python script.

I think (but I could very well be wrong) I have the Arduino side working properly and it feels as though I'm pretty close on the python side, however I don't seem to be decrypting the message properly.

An example of the string before being encrypted might be:

"55.55,24.99,0001"

Here is the code on the Arduino side:

#include <AESLib.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "DHT.h"
#include <RH_ASK.h>
#include <Base64.h>

#define DHTPIN 2

#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
RH_ASK driver;

bool takeSensorReading = true;
float h;
float t;
String str_humid;
String str_temp;
String str_out;
uint8_t key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
char data[32];
char endChar[1] = "Ʊ";

void setup() {
  driver.init();
  dht.begin();
  Serial.begin(9600);
}

void loop() {
  delay(5000);

  int messagelength = sizeof(str_out);
  byte plain[messagelength];

  h = dht.readHumidity();
  // Read temperature as Celsius
  t = dht.readTemperature();
  
  // Convert Humidity to string
  str_humid = String(h, 2);
    
  // Convert Temperature to string
  str_temp = String(t, 2);
  
  // Combine Humidity and Temperature
  str_out = str_humid + "," + str_temp + ",0001";

  str_out.toCharArray(data, 32);
  aes256_enc_single(key, data);
  
  /*aes256_dec_single(key, data);*/
  Serial.println(data);
  int encryptedStringLength = sizeof(data);

  int encodedLength = Base64.encodedLength(encryptedStringLength);
  char encodedString[encodedLength];
  Base64.encode(encodedString, data, encryptedStringLength);
  Serial.print("Encoded string is:\t");
  Serial.println(encodedString);
  
  driver.send(strcat( (uint8_t *)encodedString, endChar ), 33);
  driver.waitPacketSent(); 

  takeSensorReading = !takeSensorReading;
}

and here is the python code:

import subprocess
import json
import base64
from Crypto.Cipher import AES

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]

def print_no_newline(string):
    import sys
    sys.stdout.write(string)
    sys.stdout.flush()

def decrypt(enc):
    private_key = str(bytearray([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]))
    iv = enc[:16]
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(enc[16:]))

p = subprocess.Popen(['rtl_433', '-f', '433720000', '-F', 'json'],stdout=subprocess.PIPE,bufsize=1)
# rtl_433 -f 433720000 -F json
try:
    for line in iter(p.stdout.readline, ""):
        lineStripped = str(line).strip()
        try:
            jsondata = json.loads(lineStripped)
            time = jsondata["time"]
            payload = jsondata["payload"]
            if len(payload) == 33:
                payloadstring = ''
                for a in range(len(payload)):
                    payloadstring += chr(payload[a])
                payloadstring += "AAAAAAAAAA="
                print payloadstring
                encrypted = base64.b64decode(payloadstring)
                print encrypted
                decrypted = decrypt(encrypted)
                print decrypted
        except Exception as err:
            print "oh no, something went wrong"
            print("error: {0}".format(err))
except KeyboardInterrupt:
    p.kill()

p.wait()
p.stdout.close()

Here is an example of the erroneous output of the decrypt function:

"@g�އ�6S���25zD"

Any help you could give me in decoding the message from the Arduino in the python script would be really appreciated.

Thanks

Richard