加密认证的整个过程几乎都是围绕怎么将两个设备使用到的秘钥安全的共享,也就是当一方把密码告诉另一方时,始终要提防第三方也可能听得到这个密钥。
注意:数据包的报头和长度字段不会被加密的,这有个好处是,当接收到包时可以直接分析报头判断 SN 和 NESN 标志。
所以对于加密来说并不是加密数据有多难,而是把需要共享的密钥安全的送到正确的设备才是难点,这就引入了配对的复杂过程。
在 BLE的4.0中主要有5个密钥需要共享,这些密钥传输时一次比一次安全,有些密钥共享时并不是赤裸裸的直接传输特定密钥,而是传输计算相应密钥时使用到的参数。这5个密钥如下:
临时密钥(Temporary Key:TK)
短期密钥(Short Term Key:STK)
长期秘钥(Long-Term Key:LTK)
身份解析秘钥(Identity Resolving Key:IRK)
连接签名解析秘钥(Connection Signature Resolving Key:CSRK)
这里先解释一下,什么是配对和绑定:
配对是找到并确定需要和自己通信的设备,也就是身份确定,接着是将安全密钥共享,而这一过程仅仅是由启动加密到得到短期秘钥(STK)为止(图中的 Phase1和 Phase2)
绑定就是将长期秘钥(LTK)、 身份解析秘钥(IRK)和连接签名解析秘钥(CSRK)这3个密钥中的某个或者组合进行交换(图中的Phase3)后,将交换的这些密钥存储到数据库中的过程。
这里先讲明白一个事情:配对绑定 (图中的Phase1、Phase2 和Phase3)只有在两个设备之间第一次进行配对绑定时才会发生,那么第二次和之后的连接呢?因为有在第一次配对绑定过程中有“绑定”过程,已经将第一次的密钥进行了存储,如果这个存储的数据库没有人为的清空,那么之后的连接就不会再出现配对过程。同时还有一个问题是: 并不是所有的通信都需要加密进行数据保护,有时应用发送的数据不怕被别人听到,所以光着屁股跑也是没有关系。
配对绑定是一个三阶段的过程,前两个阶段总是使用,第三阶段是一个可选的传输特定密钥分配的阶段, 而这一个阶段的有无是由第一阶段决定,也就是没有第三阶段,相当于没有需要存储的密钥也就没有“绑定”过程。
阶段 1:配对特征交换得到临时密钥(TK)值
阶段 2:身份确认以及短期密钥(STK)生产
阶段 3:传输特定密钥
在进行设备配对时有时需要输入密码有时不需要,这是什么决定的呢?这里提到配对特征交换,为什么交换?交换了什么?交换的输入输出(IO)功能,这样设备可以知道是否能够输入密码,是否能够显示密码。但TK 的共享又并不是完全由IO决定的。也就是根据保护程度,协议中将安全分为3种特性:
Authenticated MITM protection: 可靠中间人保护
Unauthenticated no MITM protection: 不可靠无中间人保护
No security requirements: 无安全需求
MITM为 man-in-the-middle 即中间人的意思,而这里的“人”应该是第三方蓝牙设备。可靠中间人保护就是在 TK 共享是不会有第三方设备知道共享的TK 密钥;不可靠无中间人保护就是说TK共享时第三方蓝牙设备很容易知道共享的 TK 值,所以是不可靠的传输;而无保护就是光屁股在外面跑,也不怕被别人盗取数据。
IO 能力的交换决定的TK值的方式只有两种,而协议规范中其实是有三种方式决定TK值的:
Just Work:只工作----这时 TK 双方默认为 6 个 0,就是默认使用 0
Passkey Entry:输入密码----这时 TK 为输入的 6 位数 000000-999999
Out Of Band(OOB):是通过另一种无线接入两个设备的网络,同时将TK进行传送。
仅工作方式,两设备使用的是默认的TK值,即6个0。对于这种方式是一个不可靠的加密链路,它不能防止MITM攻击。这种方式使用时可靠的前提是,确保在配对绑定时能保证没有MITM攻击,那么在之后的连接中加密的数据是无法被其它设备窃听的,也就是说这种方式保护的是将来的加密链路安全,但是不能保护配对绑定过程。
上面有提到TK的共享并不会是通过无线传输的,而是通过人为方式使两个设备使用的临时密钥一样。对于输入密钥来说,实现的方式 是 : 两 个 设 备 中 , 一 个 蓝 牙 设 备 在 自 己 的 显 示 屏 上 显 示[000000,999999]之间的随机 6 位数;而操作人员看到这 6 位数后,将这 6 位数在另一个蓝牙设备中输入,从而实现两个设备的 TK 值一样。
输入的虽然是6位数,但是还是会将其前面补充0补为128bit。
上一阶段获取到的TK值是用来做什么的呢?在第 2 阶段用来作为密钥进行计算两个重要的值:
身份确认值
短期秘钥(STK)值
得到了TK值,但是为了保证和自己通信的设备是自己需要连接的设备,必须通过某些计算从而确定对方的身份。两个设备都需要计算确认值,从而确定对方是所需要的连接的设备。所以分为主机确认值 / 发 起 者 确 认 值 (Mconfirm) 计 算 和 从 机 确 认 值 / 响 应 者 确 认 值(Sconfirm)计算。确认值计算使用到的函数为 c1 函数-- (k, r, preq, pres, iat, rat, ia, ra) = e(k, e(k, r XOR p1) XOR p2)。
得到 TK 后的另一个作用是计算短期秘钥,短期秘钥的使用的函数为 s1 函数。具体的 STK 计算如下:STK = s1(TK, Srand, Mrand)。
STK存在的目的在于配对绑定过程的第3 阶段不再使用明文进行数据传输,长期秘钥 LTK 的生成依赖STK,也就是说在绑定配对过程中,第 3 阶段就已经使用加密的密文传输。
然而STK或者LTK并不能直接作为将要发送的数据包加密的密钥,为了传输的数据包更加的安全,加密数据包的密钥是会话密钥Session Key(SK),也就是说会话密钥SK是用STK或者LTK当做密钥通过加密引擎函数 e 计算得到的,计算公式如下:SK=e(LTK,(SKDslave||SKDmaste))。
在配对绑定的第3个阶段传输就是两个设备商量好了的特定的密钥,然而是不是有个问题,这些密钥到底是从哪儿来的呢?所有密钥都是通过计算得到。
长期密钥 LTK 使用的函数是d1函数。 计算如下:LTK=d1(ER,DIV,0)=e(ER,0||DIV)
Note:
可解析私有随机地址的生产和解析都需要知道设备的身份解析密钥(IRK),如果知道对方的 IRK 就能解析出对方的身份,本地设备通过 IRK 也能计算出一个可解析的随机地址,这就是身份解析密钥的功能。
在数据签名认证时需要使用到CSRK密钥,生成与LTK类似。