文章目录
https://help.aliyun.com/document_detail/57697.html?spm=a2c4g.11186623.6.621.32bf3d57fPX9zp
https://github.com/emqtt/gen_coap
https://libcoap.net/install.html
https://blog.csdn.net/weixin_42971252/article/details/105462695
一、UDP协议简介
用户数据报协议(User Datagram Protocol,简称UDP)是一种比较快的传输层的协议,因为减少了确认程序。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去。因此,与 TCP/IP 相比,UDP 的可靠性相对不高,但是比较快。对于M2M 项目的快速原型,一个非常简单的解决方案是使用 UDP,因为就 UDP 头包含很少的字节,比 TCP 负载消耗少。
TCP类似打电话,UDP类似发短信
二、COAP协议
2.1 COAP简介
CoAP是受限制的应用协议(Constrained Application Protocol)的代名词.它是一种应用层的协议,它运行于 UDP协议之上.
对于小型设备而言,实现TCP和HTTP协议显然是一个过分的要求。为了让小设备可以接入互联网,CoAP协议被设计出来。CoAP基于轻量级的UDP协议,并且允许IP多播。为了弥补UDP传输的不可靠性,CoAP定义了带有 重传机制 的 事务处理机制 。并且提供资源发现机制,并带有资源描述。
COAP RFC文档 RFC7252
CoAP核心协议 RFC 7252
CoAP资源发现 RFC 6690
COAP*
2.2 CoAP消息报文结构
一个CoAP消息最小为4个字节,以下是CoAP协议不同部分的描述。
-
【版本Version】:
类似于IPv6和IPv6,仅仅是一个版本号。 -
【消息类型Message Type】:
有四种报文类型: CON报文,NON报文,ACK报文,RST报文。 -
【COAP标识符长度】:
COAP协议中具有两种功能相似的标识符,一种是MessageID(报文编号),一种为Token(标识符).
MessageID报文编号是必须的,Token标识符是非必须的. -
【功能响应码 Request/Responses Code】:
功能响应码分为两个部分,第一个部分是Class,第二个部分是Code.如下图所示. -
【消息ID Message ID】:
每个CoAP消息都有一个ID。每发一次消息,ID都会加1.
用于客户端/服务器的 发送多个消息的 消息ID发送响应认证. -
【标记 Token】:
标记是ID的另一种表现,可以省略. -
【选项 Options】:
CoAP选项类似于HTTP请求头,它包括CoAP消息本身,例如CoAP端口号,CoAP主机和CoAP查询字符串等。
详细解释请看下方. -
【间隔符 11111111】:
用来间隔报头和负载数据的 -
【负载Payload】:
真正有用的被交互的数据
i CoAP消息结构 - 消息类型 详解
CoAP采用与HTTP协议相同的请求响应工作模式。CoAP协议共有4中不同的消息类型。
- CON——需要被确认的请求
如果CON请求被发送,那么对方必须做出响应。
如客户端发送CON报文给服务器,服务器必须响应.
- NON——不需要被确认的请求
如果NON请求被发送,那么对方不必做出回应。
- ACK——应答消息
接受到CON消息的响应。 - RST——复位消息
当接收者接受到的消息包含一个错误,接受者解析消息或者不再关心发送者发送的内容,那么复位消息将会被发送。
ii CoAP消息结构 - Requset/Response Code 详解
功能响应码分为两个部分,第一个部分是Class,第二个部分是Code.如下图所示.
为了方便描述它被写成了c.dd
结构,c表示 class(前3bit), dd表示 Code(后3bit)0.dd
表示CoAP请求的某种方法,2.dd
、4.dd
或5.dd
则表示CoAP响应的某种具体表现。
阿里云的返回码说明
iii CoAP消息结构 - Option 详解
CoAP支持多个Option,CoAP的Option的表示方法比较特殊,采用增量的方式描述,细节可参考RFC7252 #3.1
一般情况下Option部分包含Option Delta、Option Length和Option Value三部分,如上图所示.
- Option Delta】
表示Option的增量,当前的Option的具体编号等于之前所有Option Delta的总和。
增量扩展与Option长度扩展一样 - Option Length】
表示Option Value的具体长度。
如果不使用扩展的字节,Option Length为一个byte,其表示最大的长度为15.
在Option的长度大于15的时候,我们就需要使用到扩展的Option Length,该怎么Option长度扩展呢?规则如下:-
如果Option Length设置为13(
0xd
)
那么Option Length(extended)部分为1byte,即扩展255个字节,Option Length=13+Option Length(extended) -
如果Option Length设置为14(
0xe
)
那么Option Length(extended)部分为2byte,即扩展65535个字节Option Length=14+255+Option Length(extended)
-
如果Option Length设置为13(
- Option Value】
表示Option具体内容
CoAP中所有的Option都采用编号的方式,这些Option及编号的定义如下图所示。
在这些option中,Uri-Host、Uri-Port、Uri-Path和Uri-Query等和资源“位置”和参数有关。-
3】Uri-Host:CoAP主机名称,例如iot.eclipse.org
-
7】Uri-Port:CoAP端口号,默认为5683
-
11】Uri-Path:资源路由或路径,例如\temperature。资源路径采用UTF8字符串形式,长度不计第一个""。
-
15】Uri-Query:访问资源参数,例如?value1=1&value2=2,参数与参数之间使用“&”分隔,Uri-Query和Uri-Path之间采用“?”分隔。
在这些option中,Content-Format和Accept用于表示CoAP负载的媒体格式 -
12】Content-Format:指定CoAP复杂媒体类型,媒体类型采用整数描述,例如application/json对应整数50,application/octet-stream对应整数40。
-
17】Accept: 指定CoAP响应复杂中的媒体类型,媒体类型的定义和Content-Format相同。
-
CoAP协议中支持多个Option,例如
第一个Option Delta=11,表示该Option表示Uri-Path(11)
第二个Option Delta=1,表示该Option=1+11,表示Content-Format(12)
第三个Option Delta=3,表示该Option=3+1+11,表示Uri-Query(15)
CoAP采用这样的方式表示多个Option,而每种Option都可以在HTTP协议中找到对应项。
2.3 CoAP观察模式
在物联网的世界中,你需要去监控某个传感器例如温度或湿度等。在这种情况下,CoAP客户端并不需要不停的查询CoAP服务器端的数据变化情况。CoAP客户端可以发送一个观察请求到服务器端。从该时间点开始计算,服务器便会记住客户端的连接信息,一旦温度发生变化,服务器将会把新结果发送给客户端。如果客户端不在希望获得温度检测结果,那么客户端将会发送一个RST复位请求,此时服务器便会清除与客户端的连接信息。
2.4 COAP的安全性
COAP的安全性是用DTLS加密实现的。DTLS的实现需要的资源和带宽较多,如果是资源非常少的终端和极有限的带宽下可能会跑不起来。DTLS仅仅在单播情况下适用。
# 阿里云对称加密
阿里云服务器智能采集数据,不能下发数据,
阿里云先要发认证报文,才能发送数据.认证是由时间现在的,过了这段时间,就必须要重新认证
三、根据阿里云COAP规范,分析并构建十六进制的报文
3.1 阿里云物联网的 三元组,COAP中Option选项,以及负载payload 如下所示
//三元组ProductKey,DeviceName,DeviceSecret
{
"ProductKey": "a1eLpNbJ8S8",
"DeviceName": "lySmartHome",
"DeviceSecret": "3c6b7a902aa607f8ed48528c2a6be0b1"
}
//COAP中Option选项
POST /auth //POST对应Option中的uri-Path,
Host: a1eLpNbJ8S8.coap.cn-shanghai.link.aliyuncs.com //Host对应Option中的uri-Host
Port: 5682 //Port对应Option中的uri-port
Accept: application/json or application/cbor //对应Option中的Accept
Content-Format: application/json or application/cbor //对应Option中的Content-Format
payload: {"productKey":"a1eLpNbJ8S8","deviceName":"lySmartHome","clientId":"a1eLpNbJ8S8&lySmartHome","sign":"de1cfbb9c1fbea4735c04b262d84642e","seq":"1"}
payload中sign的获取:
使用device,使用HmacMD5加密方法,对clientIdXdeviceNameYproductKeyZseq1
进行加密,
其中,X表示三元组的clientId,Y表示三元组的deviceName,Z表示三元组的productKey.
加密网站点击这里
3.2 分析构造报文
- 【版本Version】及【消息类型Message Type】:
VER选择为4,
选择发送CON报文,type为0
该字段为0x4
- 【COAP标识符长度】:
不用token,长度为0:0x0
- 【功能响应码 Request/Responses Code】:
使用请求方法,POST请求:0x02
- 【消息ID Message ID】:
随便选择一个0x0101
- 【标记 Token】:
不要了 - 【选项 Options】:
-
第一个Option:uri-Host
由Option的编号及定义,我们的第一个Option为uri-Host,所以增量optionDelta为0x3
uri-host是a1eLpNbJ8S8.coap.cn-shanghai.link.aliyuncs.com
,其十六进制为61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D
,长度是46个字节.
其长度大于15个字节,所以需要扩展长度. 46 = 13 + 33,所以Option Length =0xd
,Option Length(extended) =0x21
分析得到的相关的参数:OptionDelta为:0x3
,OptionLength为:0xd21
,OptionValue为(16进制表示):61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D
所以第一个option为(16进制表示):3d 21 61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D
. -
第二个Option:uri-Port
port是5682
=0x1632
,长度是2个字节
OptionDelta是增量,前面的第一个Option uri-Host 是3,uri-Port是7,而7-3=4,所以这里的增量为4,所以optionDelta为0x4
OptionLength 为2,小于15,十六进制表示为:0x2
所以第二个option为(16进制表示):42 16 32
-
第三个Option:uri-Path
path是auth
,十六进制表示为:61 75 74 68
,长度是4个字节
OptionDelta是增量,前面的 uri-Host 是7,uri-Port 是11,而11-7=4,所以这里的增量为4,所以optionDelta为0x4
OptionLength 为4,小于15,十六进制表示为:0x4
所以第三个option为(16进制表示):44 61 75 74 68
-
第四个Option:Content-Format
Content-Format是application/json or application/cbor
,我们选择application/json
,其对应的ID是50 =0x32
OptionDelta是增量,前面的 uri-Port 是11,Content-Format是12,而12-11=1,所以这里的增量为1,所以optionDelta为0x1
OptionLength 为1,小于15,十六进制表示为:0x1
所以第四个option为(16进制表示):11 32
-
第五个Option:Accept
Accept是application/json or application/cbor
,我们选择application/json
,其对应的ID是50 =0x32
OptionDelta是增量,前面的 Content-Format 是12,Accept 是17,而17-12=5,所以这里的增量为5,所以optionDelta为0x5
OptionLength 为1,小于15,十六进制表示为:0x1
所以第五个option为(16进制表示):51 32
-
第一个Option:uri-Host
- 【间隔符 11111111】:
间隔符十六进制表示为:0xff
- 【负载Payload】:
负载为:{"productKey":"a1eLpNbJ8S8","deviceName":"lySmartHome","clientId":"a1eLpNbJ8S8&lySmartHome","sign":"de1cfbb9c1fbea4735c04b262d84642e", "seq":"1"}
其十六进制为:7B 22 70 72 6F 64 75 63 74 4B 65 79 22 3A 22 61 31 65 4C 70 4E 62 4A 38 53 38 22 2C 22 64 65 76 69 63 65 4E 61 6D 65 22 3A 22 6C 79 53 6D 61 72 74 48 6F 6D 65 22 2C 22 63 6C 69 65 6E 74 49 64 22 3A 22 61 31 65 4C 70 4E 62 4A 38 53 38 26 6C 79 53 6D 61 72 74 48 6F 6D 65 22 2C 22 73 69 67 6E 22 3A 22 64 65 31 63 66 62 62 39 63 31 66 62 65 61 34 37 33 35 63 30 34 62 32 36 32 64 38 34 36 34 32 65 22 2C 22 73 65 71 22 3A 22 31 22 7D
整理上面的数据得到我们COAP的CON报文:
40 02 01 01
3d 21 61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D
42 16 32
44 61 75 74 68
11 32
51 32
ff
7B 22 70 72 6F 64 75 63 74 4B 65 79 22 3A 22 61 31 65 4C 70 4E 62 4A 38 53 38 22 2C 22 64 65 76 69 63 65 4E 61 6D 65 22 3A 22 6C 79 53 6D 61 72 74 48 6F 6D 65 22 2C 22 63 6C 69 65 6E 74 49 64 22 3A 22 61 31 65 4C 70 4E 62 4A 38 53 38 26 6C 79 53 6D 61 72 74 48 6F 6D 65 22 2C 22 73 69 67 6E 22 3A 22 64 65 31 63 66 62 62 39 63 31 66 62 65 61 34 37 33 35 63 30 34 62 32 36 32 64 38 34 36 34 32 65 22 2C 22 73 65 71 22 3A 22 31 22 7D
3.3 UDP连接并发送设备认证报文
udp的远程主机域名:a1eLpNbJ8S8.coap.cn-shanghai.link.aliyuncs.com:5682
设备认证报文为:40 02 01 01 3d 21 61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D 42 16 32 44 61 75 74 68 11 32 51 32 ff 7B 22 70 72 6F 64 75 63 74 4B 65 79 22 3A 22 61 31 65 4C 70 4E 62 4A 38 53 38 22 2C 22 64 65 76 69 63 65 4E 61 6D 65 22 3A 22 6C 79 53 6D 61 72 74 48 6F 6D 65 22 2C 22 63 6C 69 65 6E 74 49 64 22 3A 22 61 31 65 4C 70 4E 62 4A 38 53 38 26 6C 79 53 6D 61 72 74 48 6F 6D 65 22 2C 22 73 69 67 6E 22 3A 22 64 65 31 63 66 62 62 39 63 31 66 62 65 61 34 37 33 35 63 30 34 62 32 36 32 64 38 34 36 34 32 65 22 2C 22 73 65 71 22 3A 22 31 22 7D
i. 错误响应
这里是sign生成错误而导致的.生成sign一定要细心.
ii.正确响应
返回的十六进制数据如下:
60 45 01 01 FF 7B 22 72 61 6E 64 6F 6D 22 3A 22 39 34 36 66 36 61 32 38 39 38 33 64 66 32 32 38 22 2C 22 73 65 71 4F 66 66 73 65 74 22 3A 32 2C 22 74 6F 6B 65 6E 22 3A 22 71 67 36 50 6A 7A 71 6E 61 39 48 7A 6D 62 6A 31 68 31 6E 5A 30 30 30 30 30 30 2E 36 64 66 35 22 7D
ASCII数据如下:
`E{“random”:“946f6a28983df228”,“seqOffset”:2,“token”:“qg6Pjzqna9Hzmbj1h1nZ000000.6df5”}
iii.响应解析
正确响应的 返回的十六进制数据
60 45 01 01 FF 7B 22 72 61 6E 64 6F 6D 22 3A 22 39 34 36 66 36 61 32 38 39 38 33 64 66 32 32 38 22 2C 22 73 65 71 4F 66 66 73 65 74 22 3A 32 2C 22 74 6F 6B 65 6E 22 3A 22 71 67 36 50 6A 7A 71 6E 61 39 48 7A 6D 62 6A 31 68 31 6E 5A 30 30 30 30 30 30 2E 36 64 66 35 22 7D
-
响应报文的第一个字节,
0x60
= 0110 0000
对应的VER版本号为01,
对应的Type为10,表示ACK类型的报文
对应的Token Length 为0000 -
响应的第二个字节,
0x45
= 0100 0101 =2.05
对应响应返回码:0x45
= 010 00101 =2.05
,表示正确请求.
看错误的响应:响应返回码:0x80
= 100 00000 =4.00
,表示请求发送的payload非法.
4.4 post上报数据
i 分析构造报文
//三元组ProductKey,DeviceName,DeviceSecret
{
"ProductKey": "a1eLpNbJ8S8",
"DeviceName": "lySmartHome",
"DeviceSecret": "3c6b7a902aa607f8ed48528c2a6be0b1"
}
POST /topic/${topic}
Host: ${YourEndpoint}
Port: 5682
Accept: application/json or application/cbor
Content-Format: application/json or application/cbor
payload: ${your_data}
CustomOptions: number:2088(标识token), 2089(seq)
-
【版本Version】及【消息类型Message Type】:
VER选择为4,选择发送CON报文,type为0
该字段与设备认证的一样,为0x4
-
【COAP标识符长度】:
不用token,长度为0:0x0
-
【功能响应码 Request/Responses Code】:
使用请求方法,同样是POST方法0x02
-
【消息ID Message ID】:
我们把上次的MessageID加1:0x0102
-
【标记 Token】:
不要了 -
【选项 Options】:
-
第一个Option:uri-Host,不变
3d 21 61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D
. -
第二个Option:uri-Port,不变
42 16 32
-
第三个Option:uri-Path,变了
path是/topic/sys/a1eLpNbJ8S8/lySmartHome/thing/event/property/post
注意,这里十分特殊,每个/
后的字段都是 独立Option
前面的 uri-Host 是7,uri-Port 是11,而11-7=4,所以这里的增量为4,所以optionDelta为0x4
这个Option是第一个/
后面的topic
,其十六进制为74 6F 70 69 63
,OptionLength 为5个字节,小于15,十六进制为:0x5
所以第三个option为(16进制表示):45 74 6F 70 69 63
-
第四个还是 Option:uri-Path
path是/topic/sys/a1eLpNbJ8S8/lySmartHome/thing/event/property/post
这个Option是第二个/
后面的sys
,其十六进制表示为73 79 73
,OptionLength 为3个字节,小于15,十六进制为:0x3
这个Option也是属于Option:uri-Path类型,增量为0
所以第四个option为(16进制表示):03 73 79 73
-
第五个还是 Option:uri-Path
path是/topic/sys/a1eLpNbJ8S8/lySmartHome/thing/event/property/post
这个Option是第三个/
后面的a1eLpNbJ8S8
,其十六进制表示为61 31 65 4C 70 4E 62 4A 38 53 38
,OptionLength 为11个字节,小于15,十六进制为:0xb
这个Option也是属于Option:uri-Path类型,增量为0
所以第四个option为(16进制表示):0b 61 31 65 4C 70 4E 62 4A 38 53 38
-
第六个还是 Option:uri-Path
path是/topic/sys/a1eLpNbJ8S8/lySmartHome/thing/event/property/post
这个Option是第四个/
后面的lySmartHome
,其十六进制表示为6C 79 53 6D 61 72 74 48 6F 6D 65
,OptionLength 为11个字节,小于15,十六进制为:0xb
这个Option也是属于Option:uri-Path类型,增量为0
所以第四个option为(16进制表示):0b 6C 79 53 6D 61 72 74 48 6F 6D 65
-
第七个还是 Option:uri-Path
path是/topic/sys/a1eLpNbJ8S8/lySmartHome/thing/event/property/post
这个Option是第五个/
后面的thing
,其十六进制表示为74 68 69 6E 67
,OptionLength 为5个字节,小于15,十六进制为:0x5
这个Option也是属于Option:uri-Path类型,增量为0
所以第四个option为(16进制表示):05 74 68 69 6E 67
-
第八个还是 Option:uri-Path
path是/topic/sys/a1eLpNbJ8S8/lySmartHome/thing/event/property/post
这个Option是第六个/
后面的event
,其十六进制表示为65 76 65 6E 74
,OptionLength 为5个字节,小于15,十六进制为:0x5
这个Option也是属于Option:uri-Path类型,增量为0
所以第四个option为(16进制表示):05 65 76 65 6E 74
-
第九个还是 Option:uri-Path
path是/topic/sys/a1eLpNbJ8S8/lySmartHome/thing/event/property/post
这个Option是第七个/
后面的property
,其十六进制表示为70 72 6F 70 65 72 74 79
,OptionLength 为8个字节,小于15,十六进制为:0x8
这个Option也是属于Option:uri-Path类型,增量为0
所以第四个option为(16进制表示):08 70 72 6F 70 65 72 74 79
-
第十个还是 Option:uri-Path
path是/topic/sys/a1eLpNbJ8S8/lySmartHome/thing/event/property/post
这个Option是第八个/
后面的post
,其十六进制表示为70 6F 73 74
,OptionLength 为4个字节,小于15,十六进制为:0x4
这个Option也是属于Option:uri-Path类型,增量为0
所以第四个option为(16进制表示):04 70 6F 73 74
Option:uri-Path 总汇:45 74 6F 70 69 63 03 73 79 73 0b 61 31 65 4C 70 4E 62 4A 38 53 38 0b 6C 79 53 6D 61 72 74 48 6F 6D 65 05 74 68 69 6E 67 05 65 76 65 6E 74 08 70 72 6F 70 65 72 74 79 04 70 6F 73 74
-
第十一个Option:Content-Format,不变
Content-Format 我们选择application/json
,其对应的ID是50 =0x32
增量为1,所以optionDelta为0x1
OptionLength 为1,小于15,十六进制表示为:0x1
所以第十二个option为(16进制表示):11 32
-
第十二个Option:Accept,不变
Accept 我们选择application/json
,其对应的ID是50 =0x32
增量为5,所以optionDelta为0x5
OptionLength 为1,小于15,十六进制表示为:0x1
所以第五个option为(16进制表示):51 32
-
第十三个Option是阿里云物联网云平台自定义的 CustomOptions:number:2088(token),
前面的 Accept 是17,number 是2088,而2088-17>15,所以这里需要增量扩展
增量扩展一个字节还是不够的,所以需要扩展两个字节.Option Delta 设置为0xd
又2088-17-255-14 = 1802
,1802十六进制为0x070a
, Option Delta(extended) 设置为0x070a
Option Value是qg6Pjzqna9Hzmbj1h1nZ000000.6df5
,长度为31,大于15,所以需要使用扩展字段,
扩展一个字节就够用了,Option Length 设置为0xd
扩展字段的设置的长度为 31-13 = 18,18的十六进制为0x12
,Option Length(extended) 设置为0x12
这个Option的内容是设备连接响应的token:qg6Pjzqna9Hzmbj1h1nZ000000.6df5
,其十六进制为:71 67 36 50 6A 7A 71 6E 61 39 48 7A 6D 62 6A 31 68 31 6E 5A 30 30 30 30 30 30 2E 36 64 66 35
(注意设备认证过了一段时间后,token需要重新获取)
所以第十三个Option为:ed 07 0a 12 token的16进制
-
第十四个Option是阿里云物联网云平台自定义的 CustomOptions:number:2089(token),
前面的 number 是2088,seq 是2089,而2089-2088=1,增量Option Delta为0x1
seq是一个16位的密码.16>15
扩展一个字节就够用了,Option Length 设置为0xd
扩展字段的设置的长度为 16-13 = 3,3的十六进制为0x3
,Option Length(extended) 设置为0x3
所以第十三个Option为:1d 03 seq+1生成的AES
三元组消息:"ProductKey": "a1eLpNbJ8S8",
,"DeviceName": "lySmartHome",
,"DeviceSecret": "3c6b7a902aa607f8ed48528c2a6be0b1"
设备认证返回的有用的信息:{"random":"b0317364d57dbb0d","seqOffset":4,"token":"qg6Pjzqna9Hzmbj1h1nZ000000.49a9"}
(1)构建得到SHA256明文:3c6b7a902aa607f8ed48528c2a6be0b1,b0317364d57dbb0d
(2)SHA256编码,得到:252463029285a440dffb9070c4bd69d677ebd56abeb3138f540972701f5910ba
(3)AES加密的明文,去掉前后8个字节,得到AES密钥:dffb9070c4bd69d677ebd56abeb3138f
(4)AES加密的AES初始向量:35343379686a79393761653766796667
(5)待加密的明文,第一步返回的seq值,每次计算AES加密时+1作为明文,得AES明文:35
(6)根据AES密钥、AES初始向量、AES明文,计算AES密码,AES密码:72F9E5A2EE9E04A54E75CB5D144DF14F
-
-
【间隔符 11111111】:
间隔符十六进制表示为:0xff
-
【负载Payload】:
负载为:{"method":"thing.event.property.post","id":"203302322","params":{"CurrentTemperature":33.33},"version":"1.0.0"}
其十六进制为:7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 65 76 65 6E 74 2E 70 72 6F 70 65 72 74 79 2E 70 6F 73 74 22 2C 22 69 64 22 3A 22 32 30 33 33 30 32 33 32 32 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 43 75 72 72 65 6E 74 54 65 6D 70 65 72 61 74 75 72 65 22 3A 33 33 2E 33 33 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D
需要使用AES密码对payload进行加密,得到00B7CCA8597EC06D41F5A298C1E96EADEEF97FDDE2AC94F31F6C391D67F322120ADB13FD5DDE526A5DC374B06D666773EE4EA12EA400EBB6E7FC66F5B888AE5848FD3D70A761B14A3CB1B377F625B3CEA2B98531122122561B9FA00CC1CE07A84F6C3870580E13C748AB58D7A41C6543
认证报文:
//三元组ProductKey,DeviceName,DeviceSecret
{
"ProductKey": "a1eLpNbJ8S8",
"DeviceName": "lySmartHome",
"DeviceSecret": "3c6b7a902aa607f8ed48528c2a6be0b1"
}
40 02 01 01
3d 21 61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D
42 16 32
44 61 75 74 68
11 32
51 32
ff
7B 22 70 72 6F 64 75 63 74 4B 65 79 22 3A 22 61 31 65 4C 70 4E 62 4A 38 53 38 22 2C 22 64 65 76 69 63 65 4E 61 6D 65 22 3A 22 6C 79 53 6D 61 72 74 48 6F 6D 65 22 2C 22 63 6C 69 65 6E 74 49 64 22 3A 22 61 31 65 4C 70 4E 62 4A 38 53 38 26 6C 79 53 6D 61 72 74 48 6F 6D 65 22 2C 22 73 69 67 6E 22 3A 22 64 65 31 63 66 62 62 39 63 31 66 62 65 61 34 37 33 35 63 30 34 62 32 36 32 64 38 34 36 34 32 65 22 2C 22 73 65 71 22 3A 22 31 22 7D
我们COAP的CON Post报文:
40 02 01 02
3d 21 61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D
42 16 32
45 74 6F 70 69 63
03 73 79 73
0b 61 31 65 4C 70 4E 62 4A 38 53 38
0b 6C 79 53 6D 61 72 74 48 6F 6D 65
05 74 68 69 6E 67
05 65 76 65 6E 74
08 70 72 6F 70 65 72 74 79
04 70 6F 73 74
11 32
51 32
ed 07 0a 12 token的16进制
1d 03 AES密文
ff
payload16进制密文
`E{"random":"9f4fa84d5108aa04","seqOffset":9,"token":"qg6Pjzqna9Hzmbj1h1nZ000000.7bb7"}
token的16进制:71 67 36 50 6A 7A 71 6E 61 39 48 7A 6D 62 6A 31 68 31 6E 5A 30 30 30 30 30 30 2E 37 62 62 37
SHA256明文ds,random:3c6b7a902aa607f8ed48528c2a6be0b1,9f4fa84d5108aa04
SHA256密文:40833a4c9730f661fb087a863d4c53b12853516a38ffa06e6b240ce8c85acd8d
AES加密的密钥 - SHA256密文卡头结尾:
得到:fb087a863d4c53b12853516a38ffa06e
AES初始向量:35343379686a79393761653766796667
AES明文 - seq+1的16进制:31 30
AES密文,使用工具生成 :58A439022B9FB16817321AAAD0133905
payload16进制明文:7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 65 76 65 6E 74 2E 70 72 6F 70 65 72 74 79 2E 70 6F 73 74 22 2C 22 69 64 22 3A 22 32 30 33 33 30 32 33 32 32 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 43 75 72 72 65 6E 74 54 65 6D 70 65 72 61 74 75 72 65 22 3A 33 33 2E 33 33 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D
payloadAES密文:E50819A8F8981D8C9120721872E0553891DA65F87BE4F6CC4D5D5743C6A5FCA6F2EBE9DBF67F4883489FA08101184331B47FE48C311CF40D992F2E913428468C6F0D015BCFE309EE4070A319F2A2B10F2F3F228223545B9BB8568582BBD8EF93E1B58540A7538DE04647189B291EB78D
40 02 01 02
3d 21 61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D
42 16 32
45 74 6F 70 69 63
03 73 79 73
0b 61 31 65 4C 70 4E 62 4A 38 53 38
0b 6C 79 53 6D 61 72 74 48 6F 6D 65
05 74 68 69 6E 67
05 65 76 65 6E 74
08 70 72 6F 70 65 72 74 79
04 70 6F 73 74
11 32
51 32
ed 07 0a 12 71 67 36 50 6A 7A 71 6E 61 39 48 7A 6D 62 6A 31 68 31 6E 5A 30 30 30 30 30 30 2E 37 62 62 37
1d 03 58A439022B9FB16817321AAAD0133905
ff
E50819A8F8981D8C9120721872E0553891DA65F87BE4F6CC4D5D5743C6A5FCA6F2EBE9DBF67F4883489FA08101184331B47FE48C311CF40D992F2E913428468C6F0D015BCFE309EE4070A319F2A2B10F2F3F228223545B9BB8568582BBD8EF93E1B58540A7538DE04647189B291EB78D
ii.验证:验证成功示例
得到返回的报文
60 45 01 02 E8 07 1D 12 C4 E6 57 15 C7 50 00 FF A2 2F DE FF 2F 78 32 10 0D 0D 00 33 EA DF 60 2B 93 AC 3C DB D3 69 9D 62 F7 A6 60 73 84 A4 A3 DC 9E E2 A5 AC BE AD 58 31 93 C8 11 B8 12 BB EB 56 59 E2 44 CF 41 2D 01 11 CC D4 DA 14 EC FB 99 81 D8 2C A7 C1 D7 D9 E2 1F 8E 88 A2 0D 3E 6D 54 20 9F 11 D9 4A 84 80 B3 C8 E7 F7 E6 F9 50 59 8B F6 B6 63 CF 30 B6 E8 E5 D1 36 D2 FE F3 04 E1 BF 89 55 D9 1E BC 3A BA C9 2B 3E FF 45 23 6A 1D 27 30
返回报文的payload密文(ff分隔符后面的值)
A2 2F DE FF 2F 78 32 10 0D 0D 00 33 EA DF 60 2B 93 AC 3C DB D3 69 9D 62 F7 A6 60 73 84 A4 A3 DC 9E E2 A5 AC BE AD 58 31 93 C8 11 B8 12 BB EB 56 59 E2 44 CF 41 2D 01 11 CC D4 DA 14 EC FB 99 81 D8 2C A7 C1 D7 D9 E2 1F 8E 88 A2 0D 3E 6D 54 20 9F 11 D9 4A 84 80 B3 C8 E7 F7 E6 F9 50 59 8B F6 B6 63 CF 30 B6 E8 E5 D1 36 D2 FE F3 04 E1 BF 89 55 D9 1E BC 3A BA C9 2B 3E FF 45 23 6A 1D 27 30
对payload密文解密。
解密后的payload:
7B 22 63 6F 64 65 22 3A 32 30 30 2C 22 64 61 74 61 22 3A 7B 7D 2C 22 69 64 22 3A 22 32 30 33 33 30 32 33 32 32 22 2C 22 6D 65 73 73 61 67 65 22 3A 22 73 75 63 63 65 73 73 22 2C 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 65 76 65 6E 74 2E 70 72 6F 70 65 72 74 79 2E 70 6F 73 74 22 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 22 7D 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
转化成ascii:
{"code":200,"data":{},"id":"203302322","message":"success","method":"thing.event.property.post","version":"1.0"}
iii.验证:再次post示例
修改seq值为 12 = 31 32
,重新生成seqAES密文,payload不修改。
AES明文 - seq+1的16进制:31 32
AES密文,使用工具生成 :59B15538E657151BE340B2BB5E318389
40 02 01 02
3d 21 61 31 65 4C 70 4E 62 4A 38 53 38 2E 63 6F 61 70 2E 63 6E 2D 73 68 61 6E 67 68 61 69 2E 6C 69 6E 6B 2E 61 6C 69 79 75 6E 63 73 2E 63 6F 6D
42 16 32
45 74 6F 70 69 63
03 73 79 73
0b 61 31 65 4C 70 4E 62 4A 38 53 38
0b 6C 79 53 6D 61 72 74 48 6F 6D 65
05 74 68 69 6E 67
05 65 76 65 6E 74
08 70 72 6F 70 65 72 74 79
04 70 6F 73 74
11 32
51 32
ed 07 0a 12 71 67 36 50 6A 7A 71 6E 61 39 48 7A 6D 62 6A 31 68 31 6E 5A 30 30 30 30 30 30 2E 37 62 62 37
1d 03 59B15538E657151BE340B2BB5E318389
ff
E50819A8F8981D8C9120721872E0553891DA65F87BE4F6CC4D5D5743C6A5FCA6F2EBE9DBF67F4883489FA08101184331B47FE48C311CF40D992F2E913428468C6F0D015BCFE309EE4070A319F2A2B10F2F3F228223545B9BB8568582BBD8EF93E1B58540A7538DE04647189B291EB78D
返回的payload密文
A2 2F DE FF 2F 78 32 10 0D 0D 00 33 EA DF 60 2B 93 AC 3C DB D3 69 9D 62 F7 A6 60 73 84 A4 A3 DC 9E E2 A5 AC BE AD 58 31 93 C8 11 B8 12 BB EB 56 59 E2 44 CF 41 2D 01 11 CC D4 DA 14 EC FB 99 81 D8 2C A7 C1 D7 D9 E2 1F 8E 88 A2 0D 3E 6D 54 20 9F 11 D9 4A 84 80 B3 C8 E7 F7 E6 F9 50 59 8B F6 B6 63 CF 30 B6 E8 E5 D1 36 D2 FE F3 04 E1 BF 89 55 D9 1E BC 3A BA C9 2B 3E FF 45 23 6A 1D 27 30
解密得到hex:
7B22636F6465223A3230302C2264617461223A7B7D2C226964223A22323033333032333232222C226D657373616765223A2273756363657373222C226D6574686F64223A227468696E672E6576656E742E70726F70657274792E706F7374222C2276657273696F6E223A22312E30227D10101010101010101010101010101010
转化为string:
{"code":200,"data":{},"id":"203302322","message":"success","method":"thing.event.property.post","version":"1.0"}
iv.验证:验证超时示例
a0 = 1010 0000
,表示超时了
v.验证成功示例的分析
返回的报文:60 45 01 02 E8 07 1D 12 C4 E6 57 15 C7 50 00 FF A2 2F DE FF 2F 78 32 10 0D 0D 00 33 EA DF 60 2B 93 AC 3C DB D3 69 9D 62 F7 A6 60 73 84 A4 A3 DC 9E E2 A5 AC BE AD 58 31 93 C8 11 B8 12 BB EB 56 59 E2 44 CF 41 2D 01 11 CC D4 DA 14 EC FB 99 81 D8 2C A7 C1 D7 D9 E2 1F 8E 88 A2 0D 3E 6D 54 20 9F 11 D9 4A 84 80 B3 C8 E7 F7 E6 F9 50 59 8B F6 B6 63 CF 30 B6 E8 E5 D1 36 D2 FE F3 04 E1 BF 89 55 D9 1E BC 3A BA C9 2B 3E FF 45 23 6A 1D 27 30
- VER/Type/Token Length
是60
,固定的 - Requset/Response Code
是45
,或为c.dd
形式就是2.05
,表示正确请求 - Message ID
是01 02
,正确,就是我们发送的报文的Message ID - Token
无 - Options
-
E8 07 1D
,E表示Option Delta扩展两个字节 ,07 1D
换成10进制为1821
,Option Delta = 1821 +14 + 255 = 2090
-
E8 07 1D
,E表示Option Length为8 -
12 C4 E6 57 15 C7 50 00
,这就是Option Value,这个是云消息ID,共8个字节,转化成10进制为1352459049819918300
-
得到返回的报文
60 45 01 02 E8 07 1D 12 C4 E6 57 15 C7 50 00 FF A2 2F DE FF 2F 78 32 10 0D 0D 00 33 EA DF 60 2B 93 AC 3C DB D3 69 9D 62 F7 A6 60 73 84 A4 A3 DC 9E E2 A5 AC BE AD 58 31 93 C8 11 B8 12 BB EB 56 59 E2 44 CF 41 2D 01 11 CC D4 DA 14 EC FB 99 81 D8 2C A7 C1 D7 D9 E2 1F 8E 88 A2 0D 3E 6D 54 20 9F 11 D9 4A 84 80 B3 C8 E7 F7 E6 F9 50 59 8B F6 B6 63 CF 30 B6 E8 E5 D1 36 D2 FE F3 04 E1 BF 89 55 D9 1E BC 3A BA C9 2B 3E FF 45 23 6A 1D 27 30
返回报文的payload密文(ff分隔符后面的值)
A2 2F DE FF 2F 78 32 10 0D 0D 00 33 EA DF 60 2B 93 AC 3C DB D3 69 9D 62 F7 A6 60 73 84 A4 A3 DC 9E E2 A5 AC BE AD 58 31 93 C8 11 B8 12 BB EB 56 59 E2 44 CF 41 2D 01 11 CC D4 DA 14 EC FB 99 81 D8 2C A7 C1 D7 D9 E2 1F 8E 88 A2 0D 3E 6D 54 20 9F 11 D9 4A 84 80 B3 C8 E7 F7 E6 F9 50 59 8B F6 B6 63 CF 30 B6 E8 E5 D1 36 D2 FE F3 04 E1 BF 89 55 D9 1E BC 3A BA C9 2B 3E FF 45 23 6A 1D 27 30
在阿里云物联网中,设备认证报文发送一次就行!!!
设置一次设备就足够了,可以一直使用第一次设备认证时阿里云返回的的token、random,生成后续的post上报数据报文。
四、轻量级的COAP服务器搭建
4.1 server源码下载
首先去下载microcoap server,这是一个开源的 轻量级的copa server。
microcoap github
4.2 在阿里云搭建一个Linux云服务器
科在阿里云上购买一周的云服务器ECS,学生前两个月可以免费使用,连接自行百度。
到安全组中,添加安全组规则:UDP协议,端口5683
设置实例密码,设置远程连接VNC密码。
通过VNC远程连接
验证字节设置的VNC密码,然后输入示例的用户名(默认为root
)和密码(自己设置的)进入终端界面。WIN+R
打开CMD ,ping一下公用IP,查看完了是否联通
网络联通下一步。
4.3 make编译COAP源码,运行coap server
首先下载microcoap源码到云服务器上,git clone 或者通过WinSCP。
这里用WINSCP,把下载的源码上传到云服务器中。
把下载到的microcoap_master复制粘贴到打开的远程主机中。
回到阿里云VNC界面,输入ls
查看microcoap_master文件是否复制过来了。
文件存在进入microcoap的文件夹目录,输入如下命令,编译运行coap server
make
./coap
4.4 打开网络调试助手,尽情发送数据
打开网络调试助手,选择UDP协议,设置远程主机号,发送HEX数据类型的COAP报文。
发送成功后,我们可以在VNC界面上看到发送过来的报文。以及响应的报文。