参考文献:《Guide to BluetoothSecurity》,文献链接:
https://csrc.nist.gov/publications/detail/sp/800-121/rev-2/final
蓝牙标准定义了5项安全服务:
• Authentication: verifying the identity of communicating devices based on their Bluetooth address. Bluetooth does not provide native user authentication.
• Confidentiality: preventing information compromise caused by eavesdropping by ensuring that only authorized devices can access and view transmitted data.
• Authorization: allowing the control of resources by ensuring that a device is authorized to use a service before permitting it to do so.
• Message Integrity: verifying that a message sent between two Bluetooth devices has not been altered in transit.SP.800-121r2
•Pairing/Bonding: creating one or more shared secret keys and the storing of these keys for use in subsequent connections in order to form a trusted device pair.
配对是指“Master和Slave通过协商确立link key的过程。指的是下图中的第7部分。
Master和Slave有两种可选的配对方法:legacy pairing和Secure Connections。选择的依据是:当Master和Slave都支持Secure Connections(新方法)的时候,则使用Secure Connections。否则使用legacy pairing。
对于PIN/传统配对,当用户在一个或两个设备上输入完全相同的机密的PIN码时,根据配置和设备类型,两个蓝牙设备同时获得链接密钥。下图从概念上描述了PIN码输入和密钥获得过程。注意,如果PIN码小于16字节,会用发起设备的地址(BD_ADDR)来补足PIN值以生成初始密钥。那些Ex框代表了蓝牙链接密钥获得过程所使用的加密算法。
完成链接密钥生成后,设备通过互相认证彼此来完成配对,以验证他们拥有相同的链接密钥。蓝牙配对中使用的PIN码可以是1到16个字节的二进制数或更常见的字母数字字符。对于低风险应用场景,典型的4位数PIN码可能是足够的;对于要求更高安全级别的设备,应当使用更长的PIN码(例如, 8个字符的字母数字)。
Secure Simple Pairing(SSP)通过提供一些关联模型来简化配对过程。这些模型具有适应不同设备输入/输出能力的灵活性。SSP也通过增加ECDH公钥加密来改进安全性,以防止配对过程中的被动窃听和中间人(MITM)***。
Simple Pairing配对过程如图所示,主要由下面四部分完成:
用于交换双方有关鉴权的需求(authentication requirements),以及双方具有怎么的人机交互能力(IO capabilities)。其中最重要的是IO capabilities exchange。
IO的能力可以归纳为如下的六种:
两个设备之间交换Public key。 一旦设备收到对端设备的公钥,它就可以开始计算Diffie Hellman密钥(DHKey)。耗时较多,应该尽早开始,以便用户交互可以隐藏计算时间。 在步骤8之前不需要DHKey。
当 Public key的长度大于DM1包的长度时,要使用专门的PDU来进行数据发送。
通过SMP协议进行实际的配对操作,根据阶段1 “Feature Exchange”的结果,有三种鉴权方法可选:
如果双方都支持OOB鉴权,则选择该方式(优先级最高)。由配对的双方,在配对过程之外,额外的交互一些信息(譬如NFC),并以这些信息为输入,进行后续的配对操作。这些额外信息也称作OOB(out of band),OOB的交互过程称为OOB protocol。
(man-in-the-middle)authentication,由两者方法:
Numeric Comparision方式鉴权:两个设备自行协商生成6个数字,并显示出来(要求两个设备具有显示能力),用户比较后进行确认(一致,或者不一致,要求设备有简单的yes or no的确认能力)。
Passkey Entry方式鉴权:通过输入配对码的方式鉴权。
Just Work,不需要用户参与,两个设备自行协商。
一旦设备完成鉴权过程,并且DHKey计算已完成,则检查生成的DHKey值。 如果成功,则两个设备都将完成向用户显示关于该过程的信息,否则控制器向主机发送消息以通知其停止显示该信息。
当配对过程完成后,link key就可以从DHKey中计算得到,并用做后续交互过程的输入(KEY + 明文 => 加密数据),通过HCI_Link_Key_Notification来通知host。
经过上述配对过程后,双方已经产生了加密key,因而可以建立加密的连接。加密连接建立后,可以互相传送一些私密的信息,例如Encryption Information、Identity Information、Identity Address Information等。
蓝牙设备认证过程是质询-响应方案的形式。认证过程中互动的每个设备被称为申请者(Claimant)或验证者(Verifier)。申请者是试图证明自己身份的设备,而验证者是验证申请者身份的设备。质询-响应协议通过校验一个机密的密钥——蓝牙链路密钥来验证设备。下图从概念上展示了质询-响应验证方案。
认证过程中的步骤如下图:
步骤 1. 验证者发送一个128位的随机质询(AU_RAND)给申请者
步骤 2. 申请者使用E1算法,以他或她的唯一的48位蓝牙设备地址、链接密钥和AU_RAND为输入,计算出一个认证响应。验证者执行同样的计算。只有E1输出的高32位才被用于认证的目的。128位输出中剩余的96位作为认证加密偏移(ACO)值,将被稍后用作输入以创建蓝牙加密密钥。
步骤 3. 申请者返回E1输出的高32位作为计算的响应——已签名的响应(SRES)——给验证者。
步骤 4. 验证者比较来自申请者的SRES和自己计算的值。
步骤 5. 如果两个32位值相等,认证被认为是成功的。如果两个32位值不相等,认证失败。
把这些步骤执行一遍就完成了一个单向认证。蓝牙标准允许执行单向和相互认证。用于相互认证时,验证者和申请者交换角色重复上述过程。
如果认证失败,蓝牙设备会等待一定时间间隔再做新的尝试。这个时间间隔呈指数级增长,以防止***者采用不同的链接密钥以试错法来击破认证方案。重要的是,要注意该技术不提供针对离线***的安全保证。这种***利用窃听配对帧和穷尽猜测PIN码来确定链接密钥。
注意,与认证相关的安全机制是完全基于链接密钥的保密性。虽然蓝牙设备地址和随机质询值被视为公开参数,但链路密钥不是。链路密钥是在配对过程中生成出来的,不应该在蓝牙设备之外暴露出来或通过无线链路传输。但是,链路密钥从主机到控制器(例如,PC到USB适配器)是明文传输,而当主机被用于密钥存储时情况相反。质询值是与认证过程相关的公开参数,对每次交互处理过程必须是随机且唯一的。质询值由蓝牙控制器中的伪随机数发生器生成。
如果双方都支持Secure Connection(BT4.1+)则 ,则使用Secure Authentication。
整个鉴权流程与legacy Authentication相似,不同之处在于使用了H4,H5算法,并且会进行相互认证。当配对过程使用了P-256 Elliptic Curve ,则鉴权过程应该使用Secure Authentication。
Core sepc 中流程如下:
如果有鉴权需求,则发送鉴权请求:HCI_Link_Key_Request
如果host没有可用的key给Controller,则回复HCI_Link_Key_Request_Negative_Reply;
此时Controller发送CDM HCI_PIN_Code_Request_Reply,发起pair流程来生成一个可用的key;
除了用于配对和认证的安全模式,蓝牙提供了独立的机密性服务来阻止试图窃听蓝牙设备之间交换的数据包的有效载荷。蓝牙有三种加密方式,但是只有其中两种提供实际的机密性。这些方式如下(加密方式2和3使用相同的加密机制):
如图3-7,提供给加密算法的加密密钥是使用内部密钥发生器(KG)产生的。KG产生的流密码密钥是基于:128位链接密钥(它是一个被掌握于蓝牙设备内部的机密)、128位随机数(EN_RAND)和96位ACO值。ACO是在认证过程中产生的(Legacy Authentication),如图3-5所示。
蓝牙加密过程是基于流密码,E0。密钥流输出会和有效负载位进行异或操作,然后发送到接收设备。该密钥流是利用基于线性反馈移位寄存器(LFSRs)的加密算法产生的。加密函数采用以下参数作为输入:主设备地址(BD_ADDR)、128位随机数(EN_RAND),基于微微网时钟的时隙号和加密密钥。如果加密已启用,在每个分组包传输之前,当这些参数被组合时,它们会初始化LFSRs。流密码中使用的时隙号随着每个分组包改变;加密引擎会随每个分组包被重新初始化,而其他变量保持不变。
加密密钥(KC)是从当前链路密钥算出的,并且其长度以单字节为增量在1字节到16字节间变化,其值是在主从设备间的协商过程中被设置的。在本次协商期间,主设备给从设备一个建议的密钥大小。主设备建议的初始密钥大小是被制造商编程在控制器中的,且并非总是16字节。在产品实现中,可设置一个“最小可接受的”密钥大小参数来防止恶意用户驱使密钥大小降到最小的1字节——这会使该链路的安全性变低。
重要的是,注意E0不是联邦信息处理标准(FIPS)批准的算法,且在算法强度方面没有受到详细审查。一项已公开的、理论上的已知明文***可以在2^38次计算中重新获得加密密钥,而暴力破解需要测试2^128个可能的密钥。如果通信需要FIPS认证的加密保护(例如,为了保护联邦机构间传输的敏感信息),这种保护可以通过在原生蓝牙加密之上层叠FIPS认可的应用级加密。
如图3-8所示,提供给加密算法的加密密钥是使用h3函数生成的。 h3功能根据128位链接密钥产生流密码密钥,这是一个保存在蓝牙设备中的密钥;主设备的唯一48位蓝牙设备地址;从机的唯一48位蓝牙设备地址;一个固定密钥ID“btak”;和96位ACO值。 ACO在认证过程中生成(Secure Authentication),如图3-6所示。通过获取原始加密密钥的128个最高有效位来缩短加密密钥。
蓝牙AES-CCM加密程序基于请求注释(RFC)3610,高级加密标准 - 具有密码块链接消息认证码的计数器。 AES-CCM加密功能将以下内容作为输入:加密密钥,加密随机数和有效负载位。 nonce格式有两种类型:用于ACL数据包的有效负载计数器格式和用于增eSCO的时钟格式(也包括11位日计数器) )数据包。当启用AES-CCM加密时,ACL数据包包括一个4字节的消息完整性检查(MIC)。 eSCO数据包不包含MIC。
在配对或者鉴权完成后的任何时间点都可发起加密,通过发送CDM:HCI_Set_Connection_Encryption(master或slave均可)完成。
当slave发起时,将由slave发起LMP_encryption_mode_req,但后续的
LMP_encryption_key_size_req和LMP_start_encryption_req只能通过master发起。
master可以通过该流程Change Connection Link Key,当生成新的link key后,会再次向host通知。
与上面的流程不同之处在于link key生成后会立即使用。先暂停加密过程,然后使用link key计算生成新的加密key,然后继续数据收发(使用新的加密key)。
Master使用该流程,指定使用一个temporary link key(用于加密在piconet中广播消息);或使用semi-permanent link(用于加密私有加密点对点通信)。
CMD : HCI_Master_Link_Key 中的参数Key_Flag用于指明使用那种情况。
使用semi-permanent link(用于加密私有加密点对点通信):
蓝牙BR/EDR/HS系列规范定义了四种安全模式。每个蓝牙设备必须工作于这些模式之一。这些模式以安全模式1到4命名。这些模式决定了什么时候蓝牙设备开启安全性,而不是它是否支持安全功能。
蓝牙协议定义了一系列的复杂机制,用于处理和加密key有关的操作,这就是SM(Security Manager)。图示如下:
它的主要目的是为LE设备(LE only或者BR/EDR/LE)提供建立加密连接所需的key(STK or LTK)。为了达到这个目的,它定义了如下几类规范:
1)将生成加密key的过程称为Pairing(配对),并详细定义了Pairing的概念、操作步骤、实现细节等。
2)定义一个密码工具箱(Cryptographic Toolbox),其中包含了配对、加密等过程中所需的各种加密算法。
3)定义一个协议(Security Manager Protocol,简称SMP),基于L2CAP连接,实现master和slave之间的配对、密码传输等操作。
Pairing(配对): 在SM的规范中,配对是指“Master和Slave通过协商确立用于加(解)密的key的过程”,主要由三个阶段组成:
展开如下:
1)LE legacy pairing最终生成的是Short Term Key(双方共享),生成STK之后,用STK充当LTK,并将EDIV和Rand设置为0,去建立加密连接。
2)加密连接建立之后,双方可以自行生成Long Term Key(以及相应的EDIV和Rand),并通过后续的“Transport Specific Key Distribution”将它们共享给对方,以便后面重新建立加密连接所使用:
master和slave都要生成各自的LTK/EDIV/Rand组合,并共享给对方。因为加密链路的发起者需要知道对方的LTK/EDIV/Rand组合,而Master或者Slave都有可能重新发起连接。
3)STK的生成也比较简单,双方各提供一个随机数(MRand和SRand),并以TK为密码,执行S1加密算法即可。
4)TK是在鉴权的过程中得到的,根据在阶段一选择的鉴权方法,TK可以是通过OOB得到,也可以是通过Passkey Entry得到,也可以是0(Just Work)。
注意:LE legacy pairing只能使用OOB、Passkey Entry或者Just Work三种鉴权方法(Numeric Comparison只有在LE Secure Connections时才会使用)。
LE Secure Connections pairing利用了椭圆曲线加密算法(P-256 elliptic curve),简单说明如下:
1)可以使用OOB、Passkey Entry、Just Work以及Numeric Comparison四种鉴权方法。其中Numeric Comparison的流程和Just Work基本一样。
2)可以直接生成LTK(双方共享),然后直接使用LTK进行后续的链路加密,以及重新连接时的加密。
一旦链路使用STK加密了,这两个设备就可以分配机密的密钥,如LTK、IRK和Connection Signature Resolving Key (CSRK)。
对于LE legacy pairing的LTK需要EDIV/Rand信息,因为LTK是各自生成的,不一样,因而需要一个索引去查找某一个LTK(对比后面介绍的LE Secure Connections,LTK是直接在配对是生成的,因而就不需要这两个东西)。
在分配前,需要为密钥的生成确定两个选项。设备可以简单地生成一些随机的128位值,并将它们存储在本地数据库(规范中称为“数据库查找”)。另一个选项是使用单个128位的静态但随机的值来生成这些密钥;这个值被称为带有16位变化符(DIV)的加密根(ER),它对每个受信设备是唯一的。这个选项在规范中被称为“密钥层次结构”。例如,这些密钥可以使用下面的公式从ER、DIV和标识根(IR)得出:
LTK=d1(ER,DIV,0)
CSRK=d1(ER,DIV,1)
IRK=d1(IR,1,0)
函数d1被称为多元函数,该函数基于AES-128加密。然而,规范也允许其他密钥导出函数的使用。
使用密钥层次结构的方法,设备不需要为每个受信设备存储多个128位密钥;相反,它仅需要存储其ER和每个每个设备唯一的DIV。重新连接期间,远程设备发送其EDIV(这是DIV的掩蔽版本)。然后,本地设备可根据ER和传送的EDIV来重新生成LTK和/或CSRK。如果数据加密或签名被成功设置,则验证了远程设备拥有正确的LTK或CRSK。如果不成功,则链路被丢弃。
注意,在上面的例子中,IRK是静态的和特定于设备的,因此可以先于配对过程生成。
LE Encryption要完成的事情:
数据发送方在需要发送数据的时候,按照一定的加密算法,将数据加密;
数据接收方在接收到数据的时候,按照等同的解密算法,将数据解密。
Master/Slave的LE Host会保存一个LTK(Long Term Key,至少128bits),对BLE用户(或者应用)来说,这个Key是所有加密/解密动作源头;
每当为某个LE连接启动加密传输的时候,Master和Slave的LL会协商生成一个128bits的随机数SKD(Session Key Diversifier,128bits),并以它为输入,以LTK为key,通过Encryption Engine加密生成SessionKey;
每当有明文数据包需要发送的时候,需要对明文进行加密。加密的过程,是以明文数据包为输入,以SessionKey为Key,同样通过Encryption Engine加密生成密文数据包;
同样,每当收到密文数据包的时候,需要对密文解密。解密的过程,是以密文数据包为输入,以SessionKey为Key,同样通过Encryption Engine解密生成明文数据包。
对于上述过程,我们考虑三个问题:
1)LTK是怎么来的? :由配对过程生成
2)SKD是个什么东西?怎么来的? :由下图交互生成
3)Encryption Engine又什么东西呢? :这个其实就是一个加密算法。
上面所提到的LTK和具体的加密过程相关,参考下面的sequence:
总结:
配对过程产生 :LTK(Long Term Key) STK = s1(TK, Srand, Mrand),TK是实在鉴权的过程中得到的。
开始加密协商出 :SDK(Short Term Key)
controler A(SKDm) + controler B(SKDs) ==》 128b (SDK)
IVs + IVm ==》 IV(64b)
LTK + SDK + 加密引擎 ==》 sessionKey
sessionKey + 数据PDU + 加密引擎 ==》 加密数据
转载于:https://blog.51cto.com/11134889/2108064