Search code examples
pythonencryptionaesmqtt

Python3: UnicodeDecodeError: 'utf-8' codec can't decode byte 0x83 in position 1: invalid start byte


I am dealing with MQTT communication again. I am writting a python program which implement this communication. In the publisher script, I am encrypting a message (using AES encryption) and sending it to the subscriber who will decrypt that message.

When I run the program, Iam getting that error in the subscriber part:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x83 in position 1: invalid start byte

I've searched for the solution but without any result !

This is the publisher script which works fine

import paho.mqtt.client as mqtt
import time 
from os import urandom 
from Crypto.Cipher import AES

port = 1883
brocker = "localhost"
message = "MessageToEncrypt"
topic = "Auth"
secret_key = urandom(16)
iv = urandom(16)
obj = AES.new(secret_key, AES.MODE_CBC, iv)
encrypted_text = obj.encrypt(message)

def on_publish(client,userdata,mid):
    #the mid value is the message ID 
    print("on_publish callback mid: "+str(mid))
    print("The message published is: " + message)
    print("Encrypted msg: "+str(encrypted_text))
    print(type(encrypted_text))
    
def on_connect(client, userdata, flags, rc):
    print("Client connected with this connection code: "+str(rc)) 

def on_disconnect(client,userdata,rc):
    print("client disconnected \n")

def main():
    try:
        clt = mqtt.Client("client1")
        print("Client created successfully  \n")
        clt.on_connect = on_connect
        clt.on_publish = on_publish
        clt.connect(brocker,port)
        print("Client connected \n")
        ret = clt.publish(topic,encrypted_text)
        time.sleep(4)
        print("The publish result is : "+str(ret)+"\n") 
        clt.on_disconnect = on_disconnect
        clt.disconnect()

    except Exception as inst: 
        print("\n Exception found \n")
        print(type(inst))
        print(inst.args)
        print(inst)
        print("\n")

main()

and this is the subscriber script:

import paho.mqtt.client as mqtt
import time 
from os import urandom 
from Crypto.Cipher import AES

port = 1883
brocker = "localhost"
topic = "Auth"

secret_key = urandom(16)
iv = urandom(16)
rev_obj = AES.new(secret_key, AES.MODE_CBC, iv)

def on_connect(client, userdata, flags, rc):
    print("Client connected with this connection code: " +str(rc))

def on_message(client, userdata, message):
    #print("on_message function")
    time.sleep(1)
    msg_received = message.payload
    print(type(msg_received))
    print("the encrypred message rceived is :")
    print(msg_received)
    decrypted_text = rev_obj.decrypt(msg_received)
    print("The decrypted text", decrypted_text.decode('utf-8'))

def main():
    try:

        clt = mqtt.Client()
        print(" Client created successfully  \n")
        clt.on_connect = on_connect
        clt.on_message = on_message
        clt.connect(brocker,port)
        clt.loop_start()
        clt.subscribe(topic)
        time.sleep(4)
        #print("subscribtion: successful \n")
        clt.loop_stop()

    except Exception as inst: 
        print("\n Exception found \n")
        print(type(inst))
        print(inst.args)
        print(inst)
        print("\n")

main()

and this is the output when I run the publisher script

Client created successfully  
Client connected 
on_publish callback mid: 1
The message published is: MessageToEncrypt
Encrypted msg: b'c\xf1\x9b\xfca\x081\x8e\xa1+\xe9t\x96\xdei\xdb'
<class 'bytes'>
The publish result is : (0, 1)
client disconnected 

Please don't hesitate if you have any suggestion that can help. Thank you in advance


Solution

  • Both your publisher and subscriber are generating different random key + iv

    So there is no way your subscriber can successfully decrypt the message as it doesn't have the right key + iv

    So what you get out of the decrypt function is just garbage random noise which is no way guaranteed to be valid utf-8

    The subscriber needs to have the same key + iv as the publisher.

    This has nothing to do with MQTT