LoRaWAN OTAA Join Workbench

Trace a LoRaWAN over-the-air activation from JoinRequest through JoinAccept, replay checks, receive windows, and session-key derivation.

animation
lorawan
lpwan
otaa
activation
security
join
intermediate
Interactive LoRaWAN OTAA workbench showing JoinRequest fields, MIC validation, DevNonce replay protection, JoinAccept timing, root-key use, session-key derivation, and common join failures.
OTAA join DevNonce JoinAccept Session keys

LoRaWAN OTAA Join Workbench

Step through a device join from root-key provisioning to JoinRequest, MIC and nonce checks, JoinAccept timing, and session-key derivation. Failure scenarios show why OTAA is secure only when nonces, keys, and receive windows are handled correctly.

Provisioned current join state
0x4A91 DevNonce in JoinRequest
RX1 5s selected join-accept window
Root held key material status
ProvisionDevice has DevEUI, JoinEUI, and root key before deployment.
JoinRequestDevice sends identifiers, DevNonce, and MIC.
ForwardGateway relays; it does not decrypt or join the device.
ValidateServers check registry, MIC, and nonce freshness.
JoinAcceptNetwork returns DevAddr and session parameters.
RX windowDevice listens in join RX1 or RX2 timing.
KeysBoth sides derive matching session keys locally.
UplinkNormal data can now use DevAddr and frame counters.

Scenario

A valid device joins, receives RX1, and derives fresh session keys.

Ready to join The device has identifiers and a root key. No session exists until the join succeeds.
JoinRequest current message
pending MIC and registry check
not sent JoinAccept state
none session status
LoRaWAN OTAA join sequence Animated JoinRequest and JoinAccept packets moving between device, gateway, network server, join server, and application server. End device DevEUI 70B3... Gateway transparent relay Network dedupe and route Join registry, MIC, keys No session exists yet. Provisioning is local, not an RF join. Join RX1 default is 5 seconds after TX end; RX2 follows one second later.
Join identifiers JoinEUI + DevEUI Visible identifiers route the request to the right join context.
DevNonce 0x4A91 Must be fresh for the device so captured joins cannot be replayed.
MIC cmac(root key, request) Proves possession of the root key without transmitting that key.
JoinAccept DevAddr + JoinNonce + settings Encrypted response carries the session address and receive parameters.
Root material AppKey: masked Provisioned on the device and trusted server side. It is not carried in JoinRequest or JoinAccept.
Network session NwkSKey: waiting Used by the network side for frame integrity and MAC protection in the teaching model.
Application session AppSKey: waiting Used by the application side to protect application payloads after activation.
Address and counters DevAddr: unassigned After the join, normal uplinks use DevAddr and start session frame counters.
Join diagnosis Start the animation to see where the device is accepted or rejected.
Why this matters OTAA creates a new session and DevAddr when the join succeeds, but root-key compromise remains serious.
Operational fix Persist DevNonce state, protect root keys, and use backoff when join accepts are missed.
JoinRequest fields Contains JoinEUI, DevEUI, DevNonce, and a MIC. It is not encrypted; its authenticity depends on the MIC and server registry.
JoinAccept fields Contains JoinNonce, NetID or network identity, DevAddr, DLSettings, RxDelay, optional CFList, and MIC. It is encrypted using the applicable root key.
Good security wording OTAA refreshes session keys per successful join. Do not describe this as full forward secrecy if the root key and captured join traffic are later exposed.
Technical Notes And References
LoRaWAN 1.0.x teaching model
  • Root key: AppKey.
  • Derived session keys: NwkSKey and AppSKey.
  • JoinAccept receive timing uses join delays, commonly RX1 at 5 seconds and RX2 one second later.
LoRaWAN 1.1 caution
  • Root material is split into NwkKey and AppKey roles.
  • Network-side session keys are more granular than the 1.0.x teaching pair.
  • The same high-level JoinRequest, validation, JoinAccept, and local derivation concept remains.