<h2 id="前言">前言</h2>
<p>通过OTAA方式入网的设备,通讯时使用的KEY需要通过服务器获得,在入网之间,设备无法通讯。</p>
<p>相关的OTAA入网流程已经在上一章中讲解过了,有兴趣的可以去看看**LoRaWAN协议(五)__OTAA入网方式详述**</p>
<p>这一章讲解的是OTAA中的密钥生成过程。</p>
<p>其中使用到的库函数都是从semtech的官方库中来的,官方库代码链接:<a href="https://github.com/Lora-net/LoRaMac-node">LoRaMac-node</a>。</p>
<h2 id="详解">详解</h2>
<p>设备在通讯时,会使用的密钥有NwkSKey 和AppSKey。</p>
<p>生成的公式如下:</p>
<ul>
<li>NwkSKey = aes128_encrypt(AppKey, 0x01 | AppNonce | NetID | DevNonce | pad16)</li>
<li>AppSKey = aes128_encrypt(AppKey, 0x02 | AppNonce | NetID | DevNonce | pad16)</li>
</ul>
<p>可以看到相关的参数一共有四个:<br />
1.AppNonce<br />
2.NetID<br />
3.DevNonce<br />
4.pad16</p>
<p>其中AppNonce、NetID、pad16 是产生于服务器的,DevNonce产生于node设备本身。</p>
<p>还是使用LoRaWAN协议(五)这篇文章中使用的包数据来进行分析。</p>
<p><strong>这里,我们调用官方库的接口,因为我们这里只是熟悉协议,并不是要研究Key的生成算法。</strong></p>
<p><strong>如果不明白数据协议的,可以去看LoRaWAN协议(五)这篇文章</strong></p>
<h3 id="提取devnonce">提取DevNonce</h3>
<p>1.GW->NS JSON包,从中提取出来DevNonce,</p>
<p><img alt="提取DevNonce" data-entity-type="file" data-entity-uuid="0254e37b-d995-4aae-bc6a-79eaba068961" src="/sites/default/files/inline-images/%E6%8F%90%E5%8F%96DevNonce.JPG" /></p>
<p>data为MAC层数据,为join_request message,其数据包格式为</p>
<p><img alt="数据包格式" data-entity-type="file" data-entity-uuid="ccebe75f-1f68-412c-bd53-d26029e2d861" src="/sites/default/files/inline-images/%E6%95%B0%E6%8D%AE%E5%8C%85%E6%A0%BC%E5%BC%8F.JPG" /></p>
<p>base64解码:</p>
<p>\x00 \x01 \x00 \x00 \x20 \x00 \xc5 \x26</p>
<p>\x2c \x16 \x10 \x16 \x20 \x00 \x77 \x4a</p>
<p>\x00 \x54 \x7b \x40 \x2d \xe1 \x9a</p>
<p>得到的数据:</p>
<p><img alt="数据" data-entity-type="file" data-entity-uuid="69987901-5d6a-4200-95e3-5b31f583fa90" src="/sites/default/files/inline-images/%E6%95%B0%E6%8D%AE_0.JPG" /></p>
<p><strong>可以得到DevNonce的值为0x7b54</strong></p>
<h3 id="提取appnoncenetidcflist">提取AppNonce、NetID、CFList</h3>
<p>2.NS->GW JSON包,其中txpk.data为包含了MAC层数据内容</p>
<p><img alt="MAC层数据内容" data-entity-type="file" data-entity-uuid="80654e5b-e048-42f3-8b22-e9d8948bdf5b" src="/sites/default/files/inline-images/MAC%E5%B1%82%E6%95%B0%E6%8D%AE%E5%86%85%E5%AE%B9.JPG" /></p>
<p>data base64 decode:</p>
<p>\x20 \xfa \x80 \x29 \x74 \x3b \x2d \x2f</p>
<p>\xc2 \x99 \x85 \x42 \x0f \x2f \x0a \xde</p>
<p>\x4e</p>
<p>根据LoRaWAN specification 可知,join_accept message的格式如下:</p>
<p><img alt="join_accept message的格式" data-entity-type="file" data-entity-uuid="ec7238e5-9c7a-4d4c-9160-63d5d775f1f2" src="/sites/default/files/inline-images/join_accept%20message%E7%9A%84%E6%A0%BC%E5%BC%8F_0.JPG" /></p>
<p>但是这个数据是加密的,需要使用AppKey进行解密</p>
<p>所以,我们需要先使用AppKey解密join_accept message</p>
<p>payload为join_accept message,此处为</p>
<p>\x20 \xfa \x80 \x29 \x74 \x3b \x2d \x2f</p>
<p>\xc2 \x99 \x85 \x42 \x0f \x2f \x0a \xde</p>
<p>\x4e</p>
<p>解密之后的数据存放在<strong>LoRaMacRxPayload数组中</strong>。</p>
<p>uint8_t LoRaMacAppKey[] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};</p>
<p>LoRaMacJoinDecrypt( payload + 1, size - 1, LoRaMacAppKey, LoRaMacRxPayload + 1 );</p>
<p>LoRaMacRxPayload[0] = payload[0];</p>
<p>可以得到解析之后的数组</p>
<p>0x20 0x43 0x75 0xcb 0x24 0x0 0x0 0x2</p>
<p>0x0 0x0 0x48 0x3 0x0 0x82 0xc9 0xd0</p>
<p>0xf9</p>
<p><img alt="字段解密" data-entity-type="file" data-entity-uuid="09e8735c-cab7-411e-ac74-64a008e4c638" src="/sites/default/files/inline-images/%E5%AD%97%E6%AE%B5%E8%A7%A3%E5%AF%86_0.JPG" /></p>
<p>根据协议,我们可以得到:</p>
<p>AppNonce:\x43 \x75 \xcb</p>
<p>NetID:\x24 \x0 \x0</p>
<p>DevNonce:0x7b54</p>
<p>pad16:没有</p>
<p>至此,我们就具备生成密钥的所有参数了</p>
<h3 id="产生appskey-和-nwkskey">产生AppSKey 和 NwkSKey</h3>
<p>最后,我们再调用</p>
<p>LoRaMacJoinComputeSKeys( LoRaMacAppKey, LoRaMacRxPayload + 1, LoRaMacDevNonce, LoRaMacNwkSKey, LoRaMacAppSKey );</p>
<p>就可以生成AppSKey和NwkSKey了。</p>
<p>得到的NwkSKey为</p>
<p>0xde 0x3 0x33 0x1a 0xeb 0x42 0x54 0xe9</p>
<p>0x72 0x7b 0x6f 0xaf 0xbf 0x13 0xdb 0x3d</p>
<p>得到的AppSKey为</p>
<p>0xe0 0x46 0x9e 0x44 0x9c 0x57 0x47 0x8c</p>
<p>0xbe 0xa7 0x25 0xda 0x84 0xf0 0x13 0x97</p>
<p>对比之间抓包的AS->NS的入网信息</p>
<p>AS->NS 发送入网信息,可以知道,生成的密码是正确的了。</p>
<p><img alt="生成的密码" data-entity-type="file" data-entity-uuid="fa6fc0e7-dea1-4d46-a4cf-40f805fa4738" src="/sites/default/files/inline-images/%E7%94%9F%E6%88%90%E7%9A%84%E5%AF%86%E7%A0%81.JPG" /></p>
<p>当然最好是进行实际负载的验证,我也写了两个小程序进行了验证,证明了这两个Key确实是正确的。</p>
<p>两个小程序的链接:</p>
<ul>
<li><a href="https://github.com/AnswerInTheWind/LoRaWAN/tree/master/aes_base64">deco…;
<li><a href="https://github.com/AnswerInTheWind/LoRaWAN/tree/master/generate_key">ge…;
</ul>
<p>至此,我所知的OTAA入网方面的协议就完了。</p>
<p>文章转载自:<a href="http://www.cnblogs.com/answerinthewind/" id="Header1_HeaderTitle">AnswerInTheWind</a></p>