安卓应用和蓝牙低功耗设备之间的蓝牙低功耗安全如何工作?

14

我正在学习蓝牙低功耗(BLE)协议(v4.2),尤其是它的安全特性。我试图理解移动应用程序和BLE设备之间传输的数据加密是如何工作的。

官方文档(v4.2)规定了加密数据、认证设备、生成加密和配对阶段使用的密钥等方面的方法。

第一个问题(我想确保自己已经理解了一些概念):所有这些功能都在主机级别上实现,所以如果我要加密在应用程序(Android)和BLE设备(如健身追踪器)之间传输的数据,我是否需要在BLE设备上实现(或启用)这些方法?开发人员应该只关心在BLE设备上实现这些功能,因为Android蓝牙堆栈仅支持这些功能。我的理解正确吗?如果不对,正确的实现方式是什么(包括移动应用程序和BLE设备)?

第二个问题:为什么有些BLE设备在GATT协议上实现自己的加密,而不是使用SIG提供的安全功能?
第三个问题:SIG规定的安全功能是强制性的还是可选的?
正如您看到的,我有一些疑问,也许有些问题很愚蠢,所以如果有人能够澄清如何在应用程序和BLE设备之间实现安全机制(如加密),并且这些功能是在操作系统或应用程序级别上实现的,我将非常感激。

1个回答

18

如果您使用标准的BLE加密,实际上是控制器处的链路层执行加密/解密/验证身份认证标签。但是它是主机层(SMP)定义如何配对、绑定和交换密钥的。也正是这个层告诉链路层开始使用交换的密钥进行加密。在Android和iOS上,操作系统负责管理配对和绑定,并实现了SMP。是否使用蓝牙配对/绑定/加密完全取决于设备,而且是可选的。如果不支持,则必须仍然支持发送错误代码“配对不支持”。

蓝牙标准只有一个“用例”。这个用例是提供一种方法来保护两个设备之间的连接,以便在配对后,没有人应该能够冒充设备或能够操纵或解密流量。可能您知道,“LE Legacy Pairing”,这是直到Bluetooth v4.1唯一指定的配对方法,存在几个缺陷,如果攻击者在配对过程中窃听流量,则不安全(无论是“Just works”还是“MITM/passkey entry”,但不是OOB)。然而,由Bluetooth v4.2定义的新的“LE Secure Connections”使用Diffie Hellman使其更加安全。

尽管蓝牙配对本身提供了安全性,但Android API和iOS API中仍存在一些缺陷,这些缺陷可能不足以满足应用程序开发人员需要良好安全性的要求。特别是,iOS完全没有提供任何API来检测给定设备是否实际上已绑定或链路是否加密。但它会在配对开始时向用户显示一个弹出窗口,但该应用程序不知道该配对的任何信息。因此,从iOS应用程序的角度来看,您不知道

  1. 是否已经与设备配对。
  2. 是否与真正的设备或中国制造的副本进行通信。
  3. 安全级别,即配对使用的是Just Works、MITM Legacy Pairing还是LE Secure Connections。
  4. 当前链路是否加密。

Android相对来说要好一些。至少应用程序可以知道设备是否已经配对(但无法知道其他三种情况)。还有一个API“createBond”可用于启动配对过程。在这里,Windows API要好得多,因为在执行GATT操作时,您可以强制执行加密链路。

任何这些原因都足以促使开发人员自行基于GATT实现安全性。特别是其中一个常见的用例是,开发人员想要使用PIN码或密码登录外围设备。蓝牙标准没有以任何方式支持该用例(而且不,使用“MITM受保护配对与静态密码”是不起作用的,因为该协议按设计在一次或几次尝试后就会泄露密码)。

无论如何,如果您使用自己的硬件开发自己的外围设备,并希望使用蓝牙标准的配对/绑定/加密,则BLE芯片制造商的SDK通常已经实现了这一点。但是,您仍然需要正确设置才能使其工作。通常,您只需要配置一些参数(例如,如果您有显示器或用户可以输入密码),然后其余部分由其SDK在内部自动处理。

更新:

Android的源代码可以在https://android.googlesource.com/platform/system/bt/https://android.googlesource.com/platform/packages/apps/Bluetooth/https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth找到。


2
这正是我一直在寻找的。我还有另外两个问题:我在哪里可以找到Android蓝牙堆栈的源代码?我想深入了解Android的缺陷。你能推荐一些阅读材料、资源等吗? - d3llafr33
我在答案中添加了Android蓝牙源代码的位置。关于您的第二个问题,我没有太多要说的,但如果您想询问特定问题,请告诉我。基本上,问题3和问题4非常糟糕,因为它们没有API来告知链接当前的安全性,也没有在执行GATT操作时强制执行安全级别的选项。 - Emil
我正在重新阅读官方文档。关于在LE Legacy Pairing中使用的Passkey Entry方法,用于生成STK的TK是由用户输入的passkey + padding(发起者显示并响应者输入或反之亦然)提供的。所以,根据您的回答,在Android中没有支持这些功能的API,对吗?我使用了不同的应用程序,要求我插入在设备上显示的PIN码,但我认为该PIN码并未用于创建TK,而是在某种基于GATT的身份验证或自定义加密构建中使用。我是对的吗? - d3llafr33
是的,但该对话框是由系统自动显示而不是应用程序。在传统配对中,该密码等于TK。 - Emil
非常感谢您的时间。这意味着如果使用了通行密钥,(Android)操作系统会处理请求,显示对话框,并使用用户提供的 PIN 创建 TK。所有这些功能都在操作系统中处理,而不是在应用程序级别处理,我是正确的吗? - d3llafr33
正确。但似乎仍然存在一个名为“setPin”的API,可以使用它来以编程方式输入PIN码(而不是用户输入)。但即使这样做有效,也并没有真正解决任何问题。 - Emil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接