@ironzhang
2017-01-05T07:31:42.000000Z
字数 3294
阅读 290
工作
|FixHeader|OptHeader|Payload|
// 协议命令
const (
TransportCmd = byte(0) // 传输命令
HandShake1Cmd = byte(1) // 一次握手
HandShake2Cmd = byte(2) // 二次握手
HandShake3Cmd = byte(3) // 三次握手
LanTransportCmd = byte(4) // 局域网传输命令
)
// 加密算法枚举定义
const (
None = 0 // 不加密
RSA = 1 // RSA加密
AES = 2 // AES加密
)
// FixHeader 固定头部
type FixHeader struct {
Version uint8 // 协议版本
Cmd uint8 // 协议命令
PayloadLen uint32 // Uvarint, 有效负载长度
}
// HandShake1Header 一次握手协议可选头部
type HandShake1Header struct {
Enctype uint8 // 身份认证加密方式
Identifier string // 身份, 格式: Device/ID/MajorDomainID/SubDomainID/DeviceID 或 Device/Name/MajorDomainName/SubDomainName/DeviceID. 编码: 2字节length + content
}
// LanTransportHeader 局域网传输协议可选头部
type LanTransportHeader struct {
Enctype uint8 // Payload加密方式
}
// Packet 报文
type Packet struct {
FixHeader // 固定头部
HandShake1Header // HandShake1可选头部
LanTransportHeader // LanTransport可选头部
Payload []byte // 有效负载
}
// HandShake1Msg 一次握手消息
type HandShake1Msg struct {
Enctype uint8 // 传输报文中的数据加密方式
RandStr1 [32]byte // 随机值1
}
// HandShake2Msg 二次握手消息
type HandShake2Msg struct {
Token [32]byte // 加密Token, 用于加密传输报文中的传输数据
RandStr1 [32]byte // 随机值1
RandStr2 [32]byte // 随机值2
}
// HandShake3Msg 三次握手消息
type HandShake3Msg struct {
RandStr2 [32]byte // 随机值2
}
除了固定头部和可选头部,其余协议负载可能需要加密。
以RSA加密为例
之前提出的瞬断重连不再重新握手的方案都存在安全漏洞,故还是要求瞬断之后都要重新进行三次握手。
传输层加密类似tls的方式,以Transfer报文将MQTT协议包装起来。
应用层加密只对PUBLISH报文的payload做加密
/ | 传输层加密 | 应用层加密 |
---|---|---|
加密报文 | 对所有MQTT报文加密 | 只对PUBLISH报文的payload加密 |
报文大小 | 加密会导致报文变大,特别是心跳包 | 只有PUBLISH报文的payload会大一点 |
安全风险 | 无 | 如果MQTT的CONNECT等报文中包含敏感信息,则存在泄露风险 |
|Header|Body|
|Magic|Version|Cmd|
|Cmd|ErrorNo|
|Enctype|Identifier|PayloadLen|Payload|
|RandStr1|PayloadLen|Payload|
|RandStr2|
|PayloadLen|Payload|
// 协议命令
const (
ErrorCmd = byte(0) // 错误命令
HandShake1Cmd = byte(1) // 一次握手
HandShake2Cmd = byte(2) // 二次握手
HandShake3Cmd = byte(3) // 三次握手
TransportCmd = byte(4) // 传输命令
)
// 加密算法枚举定义
const (
None = 0 // 不加密
RSA = 1 // RSA加密
AES = 2 // AES加密
)
// Packet 报文
type Packet struct {
Header // 固定头部
Error // 错误报文
HandShake1 // 一次握手报文
HandShake2 // 二次握手报文
HandShake3 // 三次握手报文
Transport // 传输报文
}
// Header 头部
type Header struct {
Magic [2]byte // magic
Version uint8 // 协议版本
Cmd uint8 // 协议命令
}
// Error 错误报文
type Error struct {
Cmd uint8 // 引起错误的协议命令
ErrorNo uint8 // 错误码
}
// HandShake1 一次握手报文
type HandShake1 struct {
Enctype uint8 // 身份认证加密方式
Identifier string // 身份, 格式: Device/ID/MajorDomainID/SubDomainID/DeviceID
PayloadLen uint32 // Uvarint, payload长度
Payload []byte // 有效负载
}
// HandShake1Payload 一次握手报文Payload中的数据格式
type HandShake1Payload struct {
Enctype uint8 // 传输报文中的数据加密方式,只能是对称加密算法或不加密
RandStr1 [32]byte // 随机值1
}
// HandShake2 二次握手报文
type HandShake2 struct {
RandStr1 [32]byte // 随机值1
PayloadLen uint32 // Uvarint, payload长度
Payload []byte // 有效负载
}
// HandShake2Payload 二次握手报文Payload中的数据格式
type HandShake2Payload struct {
Token [32]byte // 加密Token, 用于加密传输报文中的传输数据
RandStr2 [32]byte // 随机值2
}
// HandShake3 三次握手
type HandShake3 struct {
RandStr2 [32]byte // 随机值2
}
// Transport 传输报文
type Transport struct {
PayloadLen uint32 // Uvarint, payload长度
Payload []byte // 有效负载
}