In this topic we describe how to decrypt an encrypted LoRa message on an applications server. The user is assumed to know how different authentication methods and keys are used, see index topic. This topic focuses on decrypting the payload once you have received it properly.
Introduction: Customer-Side Decryption
The LoRa payload is by default encrypted with AES-128 bits encryption, based on the generic algorithm described in IEEE 802.15.4/2006 Annex B [IEEE802154] as described in the LoRaWAN specifications (section 4.3.3.) A KPN customer can choose to decrypt their payload in the KPN Thingpark platform, before they get the data forwarded to their own server. For this customers have to store the AppSKey used on the device to Thingpark. With ABP this is done manually when provisioning the device in ThingPark. With OTAA a different method is used to distribute the AppSKey to Network Server and Application Server.
This topic assumes that you choose to forward your data encrypted and know you're AppSKey and DevAddr. You will have to implement a decryption scheme on your own server. Below a schematic overview is given how to implement such a scheme and some links for examples.
Important: Decryption on your own application server is your own responsibility and should always be based on the method outlined in the LoRaWAN specifications. This topic is only meant as an elaboration on the specifications.
The plaintext is encrypted in the payload and AppSKey and DevAddr are known. The scheme works by dividing the payload in blocks of 16 bytes.
- Per block of 16 bytes payload, an AES vector is calculated and XORed with the payload block.
- The first round is done with the first 16 bytes of the payload.
- In each round an ABlock is determined by using the round of block# (so first round block#=1), resulting in the following array: [0x01, 0x00, 0x00, 0x00, 0x00, Direction (up=0, down=1), DevAddr bit 0 (LSB) , DevAddr bit 1, DevAddr bit 2, DevAddr bit 3 (MSB), FCntUp bit 0 (LSB), FCntUp bit 1, FCntUp bit 2, FCntUp bit 3 (MSB), 0x00, block#}]
- The ABlock is encrypted with the AES-128 ECB scheme using the AppSKey, resulting in an SBlock for that round.
- The 16-bytes Payload block is XORed with the 16 bytes SBlock to get part of plaintext. When the payload block is less than 16-bytes, the plaintext is retrieved by using first part of the SBlock that corresponds to the number of bytes in the payload block. For instance, when the payload block has 9 bytes, it must be XORed with the first 9 bytes of the SBlock of that round.
- By repeating rounds until all the 16-bytes blocks of the payload are decrypted, the complete plaintext is retrieved.
- Below a schematic overview of this procedure
Example implementation of the decryption scheme
On the internet, a wide variety of decryption schemes are available. Here a few:
Official reference: LoRaWAN specifications, chapter 4.3.3. MAC Frame Payload Encryption
Github C implementation: here
Github Python implementation: here
Github Java implemenation: here
Example of a payload decryption
Below an example is given on how to decrypt a small payload on a server manually
Notes on the example
- AES encrypts at bit level. In the LoRa standard we work by grouping the bit in groups of 8 to bytes. A byte has 2^8=256 positions, which are label hexadecimal from 00 to FF. All below examples assumes the user to know how to use hexadecimal byte labeling.
- A hexadecimal byte can be converted to readable text using the ASCII lookup table.
- The online tools mentioned below are only to be able to quickly check your understanding of the decryption, not to use in any application since there are not safe.