Mesh Profile (3.8)mesh安全性

(翻译自《mesh Profile v1.0》3.8 Mesh security)

安全工具箱

 

加密函数

 

CMAC函数

 

CCM函数

 

s1 SALT生成函数

 

k1导出函数

 

k2网络秘钥导出函数

 

k3导出函数

 

k4导出函数

 

序列号

序列号,是一个包含在网络层PDU SEQ字段中的24bit值。主要用于避免重放攻击(replay attacks)。

相同节点中的元素可以共享也可以不共享序列号。

对于mesh网络安全很重要的是,在每一条消息的源(every message source,根据包含在SRC字段中的源地址区分)的网络层PDU中包含一个不同的序列号

一个元素通过使用一个24bit的序列号可以在重复一个nonce之前传输16777216(2的24次方+1)条消息。

如果一个元素平均每5s钟传输一条消息,那么在重复nonce之前可以传输2.6年。

每一个元素对其生成的网络层PDU应该严格的增加序列号

在序列号达到最大值之前,元素应该通过IV更新过程更新IV索引。这也保证了序列号永远不会重复(wrap around 环绕)

IV索引

初始化向量索引是一个32bit的值。并且他是网络中一个共享的资源。(网络中所有的节点共享相同的IV索引,并且将该IV索引用于他们所拥有的子网中。)

IV索引从0x000000开始。通过IV更新过程完成增加。

IV索引增加的时间不必精确。因为IV索引的最低有效位在每一条网络层PDU中交流。

IV索引是一个32bit的值,所以一个mesh网络可以在发生重复之前,工作接近5万亿(trillion)年。

IV索引通过安全网络beacon(Secure Netwok Beacon)在一个网络中实现共享。

一个子网中收到IV更新后处理并且在子网中传播。

IV索引更新的传播通过设备在特定的子网中使用更新后的IV索引传输安全网络beacon完成。

如果一个主子网中的一个设备收到了该主子网中的更新,该设备应该传播该更新到其他的子网

如果一个主子网中的一个设备收到了其他子网中的更新消息,那么该更新消息应该被忽略。(即从主子网开始发起了IV索引更新)

如果一个设备从mesh网络中离开了一段时间。它可以扫描安全网络beacon或者使用IV索引恢复过程,从而自主的设置IV索引值。

Nonce(一个只被使用一次的任意或唯一的随机数)

nonce是一个13octec的值。对于每一条新的消息的加密都是唯一的。网络中使用了四种不同的nonce。nonce的类型由第一个octet决定。

0x00  网络nonce  用于网络层认证和加密的秘钥

0x01  应用nonce  用于高传输层认证和加密的应用秘钥

0x02  设备nonce  用于高传输层认证和加密的设备秘钥

0x04  代理nonce  用于代理认证和加密的秘钥

注意:TTL在网络nonce中使用而不是在应用nonce和设备nonce或者代理nonce中。这意味着当一个消息被中继进而TTL被减小时,应用和设备nonce并不发生改变,而网络nonce需要改变,从而允许TTL值的认证(?TTL值也需要被认证吗)

注意:DST在应用nonce和设备是nonce中使用而不再网络nonce中。这意味着应用或者设备消息的目的地需要被认证,而网络层目的地址被加密(?nonce是怎么使用,和认证是什么关系,和加密时什么关系?)。

秘钥

mesh规范中定义了个类型的秘钥:应用秘钥和网络秘钥。应用秘钥用于高传输层的安全通信,网络秘钥用于网络层的安全通信。

两种类型的秘钥在各个节点间共享。

还存在一种设备秘钥,它是一种特殊的应用秘钥。每个节点的设备秘钥是唯一的。只有该节点和配置客户端知道该节点的设备秘钥。设备秘钥用于节点和配置客户端之间的安全通信。

应用秘钥被绑定到网络秘钥上。这意味着应用秘钥只在它绑定的网络秘钥的上下文环境中使用。一个应用秘钥只能被绑定到一个网络秘钥上。

一个设备秘钥被绑定到全部的网络秘钥上。

下图阐述了应用秘钥绑定的实例。

设备秘钥

设备秘钥是一个访问层的秘钥,只有节点自己和配置客户端知道。

设备秘钥应该被绑定到节点知道的每一个网络秘钥上。这种绑定不能被改变。

设备秘钥由ProvisionSalt和ECDHSecret通过K1方法得到。

其中ProvisionSalt是一个公有值,ECDHSecret和DevKey是私有值。

应用秘钥

应用秘钥通过随机数生成器产生。

应用秘钥标识(AID)用于表示应用秘钥,通过对应用秘钥做K4方法得到。

网络秘钥

网络秘钥通过一个随机数生成器产生。(蓝牙核心定义的PartH,Volume2中涉及)

网络秘钥存在一种分层。如下图:

NID,加密秘钥和私有秘钥

每一个网络层PDU使用有NID,加密秘钥和私有秘钥组成的安全材料实现安全加密。

NID是一个7bit的值,标识了网络层PDU使用的安全材料。

注意:对于每一个NID最多有2121个可以使用的秘钥;因此,NID只能提供一个安全材料已经在网络层PDU被使用的指示。

主安全材料(相对于朋友安全材料而定义)由NID,加密秘钥和私有秘钥由安全凭证作为输入,通过K2函数得到。

NID || EncryptionKey || PrivacyKey = k2(NetKey, 0x00)

朋友关系中的安全材料通过朋友关系的安全凭证得到:

NID || EncryptionKey || PrivacyKey = K2(NetKey, 0x01 || LPNAddress || FriendAddress || LPNCounter || FriendCounter)

其中,

LPNAddress是建立朋友关系时朋友请求消息(Friend Request message)的源地址。

FriendAddress是建立朋友关系时朋友提供消息(Friend Offer message)的源地址。

LPNCounter是建立朋友关系时朋友请求消息中LPNCounter字段的值。

FriendCounter是建立朋友关系时朋友提供消息中FriendCounter字段的值。

对于在低功耗节点和朋友节点之间传输的网络层PDU需要用到朋友安全材料。

对于其他的网络层PDU,用主(master)安全材料。(这里主安全材料相对于朋友安全材料)

网络ID

网络ID有网络秘钥通过K3方法得到。每个网络秘钥生成一个网络ID。

这个网络ID是公有的信息。

标识秘钥(IdentityKey)

标识秘钥由网络秘钥得到。每个网络秘钥生成一个标识秘钥。

salt = s1("nkik")

P = "id 128" || 0x01

IdentityKey = k1(NetKey, salt, p)

Beacon秘钥

Beacon秘钥由网络秘钥得到。每一个网络秘钥生成一个Beacon秘钥。

salt = s1("nkbk")

P = "id128" || 0x01    // id128应该如何理解?

BeaconKey = k1(Netkey, salt, P)

全局秘钥索引

网络和应用秘钥组着在mesh网络中的两个列表中,通过配置客户端维护。

每一个列表是一个共享的mesh网络资源。并且每个列表最大容纳4096个秘钥。

秘钥通过全局的秘钥索引完成引用:网络秘钥索引和应用秘钥索引。

秘钥索引是一个12bit的值,从0x000到0xFFF。

索引是0x000的网络秘钥被称为主网络秘钥(Primary NetKey)

消息安全性

 消息使用AES-CCM算法在网络层和高传输层完成加密和认证。每条消息也对包中的识别信息做了混淆处理。

每条消息有一个最小64bit的认证信息。这个认证信息在网络层和高传输层可以是分开的。

控制消息不在高传输层认证,因此拥有一个64bit的NetMIC。

访问消息在高传输层认证,因此拥有一个32bit的NetMIC。(疑问:因果关系是由何建立的)

由一个单独的未分片消息发送的访问消息拥有一个32bit的TransMIC。

经过分片,通过多个网络PDU发送的访问消息既可以有32bit,也可以是64bit的TransMIC。

为了更高层次可以决定分发访问消息所需要的安全级别,因此提供了大小合适的TransMIC。

(疑问TransMIC和NetMIC的设计和作用。完整性校验)

高传输层认证和加密

对访问层数据的认证和加密在高传输层执行。

使用AES-CCM算法进行。这和BLE的加密和认证工作是完全相同的。

访问层数据使用应用nonce和应用秘钥完成加密,或者使用设备nonce和设备秘钥完成加密。(加密时为什么需要nonce?

nonce使用了序列号和源地址,保证了两个不同的节点不会使用相同的nonce。IV索引用于提供相较与序列号更多的nonce值给一个节点。

注意:访问层数据的认证和加密并不依赖于TTL值,意味着当访问层数据通过mesh网络中继是,不再需要重复加密每一跳数据。

当使用应用秘钥而且目的地址是一个虚拟地址时:

EncAccessPayload, TransMIC = AES-CCM(AppKey, Application Nonce, AccessPayload, Label UUID)

当使用应用秘钥而且目的地址是一个单播地址或者组地址时:

EncAccessPayload, TransMIC = AES-CCM(AppKey, Application Nonce, AccessPayload)

当使用设备秘钥而且目的地址是一个单播地址时:

EncAccessPayload, TransMIC = AES-CCM(DevKey, Device Nonce, AccessPayload)

加密后的访问层数据和TransMIC的级联被称作传输PDU:

Upper Transport PDU = EncAccessPayload || TransMIC

网络层认证和加密

 网络层对目的地址和传输PDU使用AES-CCM算法完成加密和认证。这和BLE加密和认证的方法是完全相同的。

所有网络PDU的加密使用一个有网路秘钥得出的加密秘钥。(见上面网络秘钥的描述)

EncDST || EncTransportPDU, NetMIC = AES-CCM(EncryptionKey, Network Nonce, DST || TransportPDU)

如何理解或||运算符在这里的表示?

网络层混淆数据

为了对网络层头部数据(CTL,TTL,SEQ,SRC)做混淆处理,这些值需要被组合到一个加密函数的结果中。从而防止通过监听网络层PDU而窃听相关身份信息。

混淆处理发生在应用和网络消息完整性校验值被计算出之后。混淆处理使用网络层PDU中可用的信息做计算。混淆处理被设计仅仅用于防止来自追踪节点的简单的被动窃听。一个有意识的攻击者仍然可以发现混淆使用的模式,进而计算出一个节点源地址或者序列号。严格的说,混淆处理并不强制加密函数的输入是唯一的。(这意味着正常加密的输入是唯一的吗

混淆处理并不能保护私钥妥协(compromise???),并且上述给出的设计考虑是用来保护被动的窃听。

认为私钥能够在足够的时间内被妥协(compromise???)。

混淆处理的设计中包含IV索引,因此当IV索引发生改变是,任何混淆攻击都需要从新开始。

为了混淆网络层PDU,对已经被加密的网络层PDU的头6个octet和IV索引以及私钥做结合处理

这些已经被加密的网络层PDU的头6个octet包含了DST(目的地址)。并且可以包含最多4个加密后的传输层PDU(EncTransportPDU)中的octet和(或者)NetMIC字段。这些octets被称为私有随机值(PrivacyRandom Value)。

私钥来自于通过网络秘钥经过生成函数的计算(见上网络秘钥的描述),用于保护网络秘钥,即使私钥被破译。(compromised)。

密码学中对于秘钥的破解被称作 be compromised 吗???

IV缩影和私有随机值级联,并和私钥一起作为加密函数的输入。输出被称作PECB值。

PECBD的头6个octet和TTL,序列号,源地址字段做exclusive-ORed,进而得到混淆数据。

网络层PDU依次连接了NID/IVI,混淆数据,EncDST和EncTransportPDU和NetMIC。

Privacy Random = (EncDST || EncTransportPDU || NetMIC)[0~6]

PECB = e(PrivacyKey, 0x0000000000 || IV index || Privacy Random)

ObfuscateDate = (CTL || TTL || SEQ || SRC) 异或 PECB[0~5]

在翻转运算时:

Privacy Random = (EncDST || EncTransportPDU || NetMIC)[0~6]

PECB = e(PrivacyKey, 0x0000000000 || IV index || privacy Random)

(CTL || TTL || SEQ || SRC) = ObfuscatedData 异或 PECB[0~5]

消息重放(replay)保护

 一个合法发送的消息可以被攻击者被动的接收然后不加修改的重播。这种攻击称作重放攻击。

由于发端元素加密和认证消息使用正确的秘钥,接收者不能通过消息完整性检验确定该消息是否是一个重放攻击。

为了对重放攻击增加保护,每一个元素增加它发出的每一条消息的序列号。如果一个来自发端元素有效的消息已经被通过一个特定的序列号接收,那么之后收到的包含低于或者等于相同序列号的消息应该被丢弃。因此,消息应该按照序列号顺序在访问层传输。疑问:如果后发出的消息被先接收到怎么办?

如果一个来自相同发端元素的更低的IV索引的消息被接收,这条消息应该被丢弃。

一个节点应该实现对于来自其他节点和代理配置客户端的访问消息和控制消息的重放保护。

如果一个节点没有足够的资源对于一个给定的源地址执行重放保护,那么这个节点应该在处理后立即丢弃消息。

重放保护的实现可以在任意层和以任何遵守消息认证步骤的顺序中(网络层解密和传输层解密),从而优化消息的处理流程,密码操作的次数和内存消耗。

然而,实现应该遵循基本的需求,即既可以确定一条消息是否属于重放,或者应该立即丢弃。

(这个图中存在消息没有发到,确认没有发到的情况。需要注意。)

posted on 2018-10-20 23:43  minnowbin  阅读(1288)  评论(0编辑  收藏  举报

导航