Here is a little python script that shows the decryption.
Your message starts at frame ctrl and stops before rssi.
from Cryptodome.Cipher import AES
data_string = "043e25020103008b98c54124f819181695fe5830b603368b98c54124f88bb8f2661351000000d6ef"
aeskey = "b853075158487ca39a5b5ea9"
# frame dev ct ---mac------ ----encrypted payload- rssi
# ctrl id cipherpayld- -cnt-- tk
# 043e25020103008b98c54124f819181695fe 5830 b603 36 8b98c54124f8 8bb8f2661351 000000 d6 ef
data = bytes(bytearray.fromhex(data_string))
key = bytes.fromhex(aeskey)
key_1 = key[0:6]
key_2 = bytes.fromhex("8d3d3c97")
key_3 = key[6:]
key = b"".join([key_1, key_2, key_3])
print("key: ", key.hex())
xiaomi_index = data.find(b'\x16\x95\xFE')
xiaomi_mac_reversed = data[xiaomi_index + 8:xiaomi_index + 14]
print("reversed mac: ", xiaomi_mac_reversed.hex())
# reversed mac: 8b98c54124f8
framectrl_data = data[xiaomi_index + 3:xiaomi_index + 5]
print("frame ctrl: ", framectrl_data.hex())
# frame ctrl: 5830
device_type = data[xiaomi_index + 5:xiaomi_index + 7]
print("device type (product id): ", device_type.hex())
# device type (product id): b603
encrypted_payload = data[xiaomi_index + 14:-1]
print("encrypted payload: ", encrypted_payload.hex())
# encrypted payload: 8bb8f2661351000000d6
packet_id = data[xiaomi_index + 7:xiaomi_index + 8]
payload_counter = b"".join([packet_id, encrypted_payload[-4:-1]])
print("payload counter: ", payload_counter.hex())
# payload_counter: 36000000
nonce = b"".join([framectrl_data, device_type, payload_counter, xiaomi_mac_reversed[:-1]])
print("nonce: ", nonce.hex())
# nonce: 5830b603360000008b98c54124
aad = b"\x11"
token = encrypted_payload[-1:]
print("token: ", token.hex())
# token: d6
cipherpayload = encrypted_payload[:-4]
print("cipher payload: ", cipherpayload.hex())
# cipher payload: 8bb8f2661351
cipher = AES.new(key, AES.MODE_CCM, nonce=nonce, mac_len=4)
cipher.update(aad)
decrypted_payload = cipher.decrypt(cipherpayload)
print("decrypted payload: ", decrypted_payload.hex())
# decrypted payload: 01100300ff04
The decrypted payload can be read as follows.
0110 = Button (= type of message according to the MiBeacon protocol)
03 = length of data
00 = button
ff = value
04 = press
button, value and press are the names I use in BLE monitor, depending on the device type, they are translated to a message. See the def obj0110(xobj):
function in https://github.com/custom-components/ble_monitor/blob/master/custom_components/ble_monitor/ble_parser/xiaomi.py. In this example, press 04 + button = 0 means "rotate left" with (256 - 255(= ff) = 1 steps.
I also tried your BLE advertisement + beaconkey, but it doesn't seem to be right, I get this as result.
decrypted payload: ab330e5cbc82
Originally posted by @Ernst79 in #1 (comment)