End-to-End Payload Encryption
TEKTELIC Network Server can provide end-to-end payload encryption between the Device and the Customer Application.
In this case Network Server will not be able to decrypt and access the UL/DL payload content.
The payload can be decrypted on the Customer Application side using the customer provided encryption key.
To facilitate the decryption process TEKTELIC provides Docker image of the decrypting service that can be run on Customer’s side.
- Receive Application Server credentials from TEKTELIC (used in following steps)
- Set up Key Encryption Key (KEK)
- Claim the device
- Set up NS converter
- Set up NS HTTP Integration
- Run the decrypting service
- Process the plaintext UL payload
- Send plaintext DL payload
Contact TEKTELIC to receive credentials for setting up the End-to-End encryption feature.
Choose your KEK (random 16-byte hex string) and set it up on TEKTELIC Join Server using the following API call:
curl -X 'PUT' \
'https://lorawan-js.tektelic.com/v1/clients/as/{AS_ID}/kek' \
-H 'accept: */*' \
-H 'Authorization: Basic {basic_creds}' \
-H 'Content-Type: application/json' \
-d '{
"label": "{kek_label}",
"kek": "{kek}"
}'
{AS_ID}
- unique application server ID provided by TEKTELIC{basic_creds}
- Base64 encoded string of{AS_ID}:{password}
provided by TEKTELIC{kek_label}
- label of AS KEK. Should be unique.{kek}
- 16-byte hex string that will be used as KEK
Claiming of device means configuring it be used with specific NS and AS. This should be done for each device that is to use End-to-End encryption. Use the following API to claim the device:
curl -X 'POST' \
'https://lorawan-js.tektelic.com/v1/claim/{devEUI}' \
-H 'accept: application/json' \
-H 'Authorization: Basic {basic_creds}' \
-H 'Content-Type: application/json' \
-d '{
"homeNetID": "{netId}",
"homeNSID": "647FDAFFF0000000",
"ownerToken": "{ownerToken}"
}'
{devEUI}
- Device EUI{basic_creds}
- Base64 encoded string of{AS_ID}:{password}
provided by TEKTELIC{netId}
- Provider’s NetID{ownerToken}
- Device’s Owner token provided by TEKTELIC (8 bytes hex string)
Create a Custom V2 converter with the following functions:
function decodeUplink(input) {
return {
"data": {
"bytes": input.bytes
},
"errors": [],
"warnings": [],
"tektelicMetadata": input.tektelicMetadata
};
}
function encodeDownlink(input) {
return {
"fPort": input.data.fPort,
"bytes": input.data.bytes,
"errors": [],
"warnings": []
};
}
Create an HTTP V2 integration with the previously created Converter and the following parameters:
- Application address - your Decrypting Service host
- Port - your Decrypting AS port
- Base path -
/api/uplink
Make sure your NS Application has SendPayloadEncrypted checkbox unchecked (!)
Create a copy of example.env
file to specify custom parameters and run the docker container like this:
docker run -p 8080:8080 --env-file ./test.env tektelicdocker/decrypting-application-server:1.0.0
The .env
file has the following format:
AS_KEK_LABEL=as-kek
AS_KEK=AAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCC
UPSTREAM_HOST=http://localhost:8082
NS_HOST=https://lorawan-ns-na.tektelic.com
NS_BASE_PATH=/api/v2/integration/http/069ba6b3c2514e299ec23a8c0c23468c42f67af6aaa84c5e82f1d766027c34f3
AS_KEK_LABEL
- your AS KEK labelAS_KEK_LABEL
- your AS KEK hex stringUPSTREAM_HOST
- where to send your plaintext UL payload (HTTP server)NS_HOST
- NS host (for sending DLs)NS_BASE_PATH
- base path of your NS HTTP integration (for sending DLs)
Decrypted UL is delivered to the UPSTREAM_HOST
in the POST request using the following format:
{
"decryptedHex": "AABBCCDDAABBCCDDAABBCCDDAABBCCDD",
"deviceEui": "647FDA0000000000",
"deviceName": "Device Name",
"deviceClass": "A",
"deviceModelId": "aaa1b0a0-aa11-11aa-1a11-a1aaa11a11aa",
"deviceModelName": "Tektelic Home Sensor",
"applicationId": "aaa1b0a0-aa11-11aa-1a11-a1aaa11a11a1",
"applicationName": "Application Name",
"fPort": 10,
"adrBit": true,
"ackBit": true,
"fCntUp": 142,
"fCntDown": 42,
"recvTime": 1345291148,
"devAddr": "076d51cf",
"confirmed": true,
"dataRate": 7,
"uLFreq": 866100000,
"margin": -32,
"battery": 20,
"devStatusTimeMillis": 1662382555000,
"rfRegion": "US902",
"gatewayCount": 1,
"gatewayRxInfo": [
{
"gwEui": "647FDAFFFE000000",
"antennaId": 0,
"rssi": -100,
"snr": 9.5,
"lat": 123.0,
"lon": 123.0,
"alt": 10.0,
"gatewayName": "Gateway Name",
"channel": 0,
"codeRate": "4/5",
"crcStatus": 1,
"dataRate": {
"modulation": "LORA",
"spreadFactor": 10,
"bandwidth": 125
},
"gwTimeUtcMillis": 1558015672000,
"gwTimeGpsMillis": 1242050890000,
"rsig": null
}
]
}
decryptedHex
- plaintext FRMPayload (decrypted) in hex-string format
In order to send a DL to device, send the POST request in the following format:
POST {DECRYPTING_SERVICE_HOST}:8080/api/downlink
{
"deviceEui": "AABBCCDDAABBCCDD",
"confirmed": true,
"fPort": 10,
"payloadHex": "AABBCCDD",
"msgId": "123",
"fCntDown": 1,
"devAddr": "AABBCCDD",
"appSKey": "AABBCCDDAABBCCDDAABBCCDDAABBCCDD"
}
payloadHex
- plain payload to be encrypted
Optional fields:
msgId
- Identifier of the DLfCntDown
- FCntDown of the DL (if it is known to the Application)devAddr
- DevAddr of the device (if it is known to the Application)appSKey
- plaintext AppSKey of the device (if it is known to the Application)