HTTPS
The obvious way of securing a HTTP REST API is utilizing the PKI infrastructure and accessing the AS via HTTPS. HTTPS enabled web sites require a certificate validated by a CA that is part of the PKI infrastructure. If your AS does not have a certificate yet, you can get one for free from Let’s Encrypt.
Checking the integrity of messages received from the NS
Utilizing HTTPS and the PKI infrastructure for uplink messages will just secure the identity of the AS. This is not enough. We also need a way to secure the identity of the NS. The AS has to be able to check if the received message was really sent by the NS and not by someone else.
For that the NS generates a unique Token for every uplink message and sends it as a query parameter like it was illustrated by the above presented curl command.
Once the AS receives a new message it has to recalculate the token and compare it with the one received as a query parameter. If the 2 tokens are the same, the message integrity is correct, otherwise the AS has to drop the message.
The Token Verification Procedure is as follows:
- The NS sends the following message to the AS
curl \
-X POST \
-H "Content-type:application/json" \
-d '{ "DevEUI_uplink": { ... "DevEUI": "000000000F1D8693", "FPort": "2", "FCntUp": "7011", "payload_hex": "0027bd00", "CustomerID": "100000507" ... } }' \
"?LrnDevEui=000000000F1D8693&LrnFPort=2&LrnInfos=UPHTTP_LAB_LORA&AS_ID=app1.sample.com&Time=2016-01-11T14%3A11%3A11.333%2B02%3A00&Token=fd0b0b00464aa798a59282d64eaa70813e33bff87682880db49638569d096aad"
- The AS cuts out the queryParameters subsring from the original query string of the http request without the Token
queryParameters =
"LrnDevEui=000000000F1D8693&LrnFPort=2&LrnInfos=UPHTTP_LAB_LORA&AS_ID=app1.sample.com&Time=2016-01-11T14%3A11%3A11.333%2B02%3A00"
- The AS builds the bodyElements string as the concatenation – without separator – of the following values taken from the http request body:
bodyElements = CustomerID + DevEUI + FPort + FCntUp + payload_hex
- The AS re-computes the Token as:
Token = SHA-256(bodyElements + queryParameters + AsKey)
Where: AsKey is the 128 bits pre-shared Tunnel Interface Authentication Key (lower case hexadecimal string representation) between the AS and the NS as defined in the Generic Application configuration.
- The AS compares the calculated Token with the received token (in the query string). If the two are not the same the AS drops the uplink frame.