Trouble generating app session key

Hello. I am having trouble generating a matching app session key when joining using otaa with loraserver and a 1.0.3 endpoint. I am generating the correct matching network session key but my appskey does not match what loraserver is displaying in the activation tab. I must be missing something because it appears the appskey is generated the same way as the nwkskey but with a 2 instead of 1.

I’ve taken my join request packet(devnonce) and the join accept response(appnonce, devid) packet from loraserver and put it in a python script to generate the session keys. Can anyone tell me my my nwkskey matches loraserver but my appskey does not?

appkey=bytearray(b'CD0D7B3BCB116F5B6A05E48E78CC949B')

# join accept message send from loraserver to endpoint
msg=base64.b64decode('ipxY0zD5Q33Xfh7phRmI8krzDxLU5u/fCQPL6A==')
mic=bytearray(b'cea32dc0')

data = aesEncrypt(binascii.unhexlify(appkey), msg+binascii.unhexlify(mic))
print('Plain Text join accept:',binascii.hexlify(data))

appnonce=0x0011
netid=0x000000
devnonce=36580

data = struct.pack('B', 1) + \
    intPackBytes(appnonce, 3, endian='little') + \
    intPackBytes(netid, 3, endian='little') + \
    struct.pack('<H', devnonce) + intPackBytes(0, 7)
print('Data to encrypt for nwkskey:', binascii.hexlify(data))
cipher = AES.new(binascii.unhexlify(appkey),AES.MODE_ECB)
nwkskey = cipher.encrypt(data)
    
print('nwkskey',binascii.hexlify(nwkskey))
data = struct.pack('B', 2) + \
    intPackBytes(appnonce, 3, endian='little') + \
    intPackBytes(netid, 3, endian='little') + \
    struct.pack('<H', devnonce) + intPackBytes(0, 7)
print('Data to encrypt for appskey:', binascii.hexlify(data))
cipher = AES.new(binascii.unhexlify(appkey),AES.MODE_ECB)
appskey = cipher.encrypt(data)

print('appskey',binascii.hexlify(appskey))

OUTPUT:
Plain Text join accept: b'11000000000048bd94000801ffffffffffffffffff000000000000011ff26a3d'
Data to encrypt for nwkskey: b'01110000000000e48e00000000000000'
nwkskey b'1d92cad7377a58646061c11bafd4d5bf'
Data to encrypt for appskey: b'02110000000000e48e00000000000000'
appskey b'b9af585d7d83f3349f73d66fcf54ed75'

Capture

Can someone tell me what I’m doing wrong? If the nwkskey is correct shouldn’t the appskey also be correct?

BTW here is a handy lorawan decoder:
https://lorawan-packet-decoder-0ta6puiniaut.runkit.sh/

1 Like

Found my answer in the standard:

I saw Loraserver updated the appskey after it received the first packet from the endpoint. It is strange that the nwkskey gets updated but not the appskey. This doesn’t quite follow the standard because if the endpoint did not receive the join accept and reverts back to previous good keys loraserver has a combination of old and new session keys.

If you think this is an issue in the code-base, please create a GitHub issue :slight_smile: https://github.com/brocaar/loraserver

I was wondering why i am getting error saying “invalid MIC” on the application server, and “get device-session error: invalid MIC” on the network server but still keep on having successful communication between app server and end device (im using OTAA). Other posts pointed out that issue might be in MSB and LSB order of the keys, and that might be the case if you’re NOT having ANY successful communication.
Now i figured that issue is probably caused by what @gradoj pointed out. network session keys gets updated on join request and application session key does not. App key gets updated only after the first uplink (after join request) and then communication goes smoothly without invalid MIC error.
Ive seen issue of this being closed but it still seems to be a problem. Version of my application server is 3.11.0 and network server 3.10.0