Wednesday, May 25, 2016

Decoding a LoraWAN payload send by your ESP8266 gateway



If you are receiving a LoraWAN packet on you LoraWAN gateway using the ESP8266 module most probably  you will forward it to a back-end server to be processed by your application. But the message is encoded and encrypted so this is the procedure to do it right.


rxpk update: {"rxpk":[{"tmst":1060664170,"chan":0,"rfch":0,"freq":868.100000,"stat":1,"modu":"LORA","datr":"SF7BW125","codr":"4/5","lsnr":12,"rssi":-28,"size":31,"data":"QGIH4AIAqgABvJNVF4DpUapp/xQN1REVnI+jYoR6Ig=="}]}




Step1. Base64

The "data":"QGIH4AIAqgABvJNVF4DpUapp/xQN1REVnI+jYoR6Ig==" need to be decoded using base64 and the result will be:

64, 98, 7, -32, 2, 0, -86, 0, 1, -68, -109, 85, 23, -128, -23, 81, -86, 105, -1, 20, 13, -43, 17, 21, -100, -113, -93, 98, -124, 122, 34





Step 2. Build the block A(i) according to the 4.3.3.1 

For each data message, the algorithm defines a sequence of Blocks Ai  for i = 1..k 
with k = ceil(len(pld) / 16). In our case the k=2 because the len(pld)=31 so there are 2 blocks that need to be constructed.

An A Block will be like this one:

-----------------------------------------------------------------------------------------------------------
                          | Dir | Device Address     | Fcnt Up/Down       |      | Block number     
-----------------------------------------------------------------------------------------------------------
0x01 | 0x00 0x00 0x00 0x00| 0x00| 0x62 0x07 0xE0 0x02| 0xAA 0x00 0x00 0x00| 0x00 | 0x01



-----------------------------------------------------------------------------------------------------------
                          | Dir | Device Address     | Fcnt Up/Down       |      | Block number     
-----------------------------------------------------------------------------------------------------------
0x01 | 0x00 0x00 0x00 0x00| 0x00| 0x62 0x07 0xE0 0x02| 0xAA 0x00 0x00 0x00| 0x00 | 0x02


Where Dir is direction and it is 0 for uplink and 1 for downlink



Step 3. Encrypt each A Block

The blocks Ai are encrypted to get a sequence S of blocks S(i) :  S(i) = aes128_encrypt(K, Ai) for i = 1..k

So, on this step each A block will be encrypted ( yes encrypted !!!) AES128 with the same
key used on node side. 

A ciphertext will be like:

c7b11d72ec853e8853dd4362a77d71ad



Step 4. XOR the cipher with payload.

S = S1 | S2 | .. | Sk

Don't forget that encryption and decryption of the payload is done by truncating (pld | pad16) XOR S to the first len(pld) octets.


At the end the text {"Hello":"World1"} will be available for your application. If at the node side this text is encrypted your app will need to do a decryption to get it.





1 comment:

  1. Hi, can you give the sample code to decode the payload?

    ReplyDelete