AES key decoding

Can it be used in payload decoder, aes key js decoding function, because I have a mbus packet coded with aes key.?
decoded base64 to hex wmbus packet:
aes key: CB6ABFAA8D2247B59127D3B839CF34B4
“EncryptionMode”: 5,
“EncryptionModeString”: “AES with CBC”,
“EncryptedBlocks”: 2,
anyone have an idea how to decode this message, some example or link how to use aes decoder in custom payload decoder?

Hi Nikola,

have you got resolution for this? Can you help me with same problem?

I send my wMBus data to MQTT => NodeRED to decode. My wMBus-Bridge (Lobaro) sends the data divided in two parts I have to concat first in NodeRED.

For AES decryption I use the node.js library. It’s easy usable in NodeRed but I think not in Chirpstack decoder.

The wMBus protocol is quiet difficult to analyse and I am more flexible in NodeRED than within the Chirpstack decoder.

Many tnx fromcologne, do you want to send me nodered flow

very big problem is to decode AES in chirpstack
I really do not how to do that and how to add some library to ChirpStack

i used influxdb integration and type wmbus raw message into the database directly

“do you want to send me nodered flow”

I´m sorry it´s company property but I can describe the strategy.

WMBus is a quiet difficult protocol and the frame from the heat meter I use is so long that lorawan needs two or more frame to transmit it.
The wmbus/lorawan-bridge I use decodes the numbering of the parts in fPort.

Write a Chirpstack decoder that output an object consisting of

  • hexstring of the wmbus frame part
  • number of this part
  • total number of parts
    Concatenation can´t be done in Chirpstack because of different uplink messages.

In NodeRED (NR) subscribe to the MQTT broker and use a JOIN node to concat the wmbus frames. Now you have one complete frame you can decode.

Download the protocol specification:

Especially the examples in Annex N are very helpful.

Install in NR the BUFFER-PARSER node.

A wmbus frame consists of a lot of data fields. Some are encodes bytewise, some LSB, some BCD, some date/time. Read the documentation.
A hint: in the examples Annex M they start counting of bytes with 1. In javascript we start with 0. In the example they count the CRC fields too. The wmbus frame I get from the wmbus/lorawan-bridge does not contain CRC bytes.

Start with decoding the Data Link Layer (DLL). Byte 0 to 10.

BUFFER-PARSER: output property: msg.payload; output: object

Type: uint8; name: "parsed_L_Field"; length: 1; offset: 0; no mask
Type: unit8; name: "parsed_C_Field"; length: 1; offset: 1; no mask

offset is the number of the byte in the wmbus-frame.
name is the name of this data field from documentation

You get an object like this:


Look at the TPLCi_Field and in the documentation. This fields gives info which kind of header follows.
You can use in NR a SWITCH node. The following header I think depends on the manufacturer of the meter hardware and the type of AES encryption.

If there is no encryption or security mode 5 then an Transport Layer header follows.
If there is security mode 7 then an Extended Link Layer follows.

Use the next BUFFER-PARSER node to decode the Transport Layer. Byte 11…13.
The data field “parsed_CF_Field” is bitwise encoded and gives information about the used Security Mode (see documentation).

If you find Security Mode 5 (aka Security Profile A) AES decrypting is quiet easy. Profile B is more difficult.


First you have to isolate the AES encrypted part of the wmbus frame. The start is byte 15, the length is encoded in the “parsed_CF_Field” within four so called N-Bits. Further down it´s called cryptBlock.

The aes-js package works with buffers. So you have to hexstring => buffer.
There is only one AES-key you need, the persistant key (PK). You get it from the hardware manufacturer.
In the documentatation you find a recipe to generate the IV vector from the data fields M_field, A_field, TPLACC_Field. Transform their values to buffer and concat them. You will get an buffer with the IV vector.

And this is the magic. Within a FUNCTION node:

var aesjs =   require('aes-js');
aesCBC = new aesjs.ModeOfOperation.cbc(PK, IV);
var decryptBlock_Obj = aesCBC.decrypt(cryptBlock);

You can check if the decryption works if you find 0x2F in the end of your result.
These are fill bytes.

The decrypted wmbus frame you can parse again with an BUFFER-PARSER to get the metering values. How they are decoded you find in the documentation [1] and here

I started the development of this NR flow with an INJECT node filled with an hexstring from the values of an example of [2]. Look for an SND-NR frame. This is the intersting frame containig the metering data. And choose your Security Profile.
These examples are very well described with all the AES keys you need.

Thank you very much for the good guidance … I am very grateful to you. Here I take to read right away

You can decode it using wmbusmeters like this:
wmbusmeters <hex>

wmbusmeters <hex> MyHeater qheat <id> <aeskey>

This particular meter has not been added yet, so the qheat driver misses the volume field. You can open an issue here:

1 Like