This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to bond devices using the Android BLE library

Hi there,

This is actually a question re. the Android BLE library (https://github.com/NordicSemiconductor/Android-BLE-Library), so please re-direct me if necessary.

My question is in relation to bonding. I use the BLE library to connect to another Android device with the peripheral role. The GATT service on the peripheral has a characteristic requiring encryption. Therefore, when I use the BLE library to read the peripheral's characteristics, a pairing UI sequence ensues. However... the peripheral first displays a pairing dialog without the central device displaying one. If I then accept the peripheral's pairing request dialog then both the peripheral and the central (BLE library) devices display a dialog.

I experienced this behaviour prior to using the BLE library, when I used the Android APIs directly on the central device, so I don't think this is an issue with the BLE library per se.

I'm left wondering how others go about the process of bonding though. I've been working on getting bonding to work nicely on Android for a couple of weeks now, and Android is winning. Do people rely on users using the Android pairing UI of settings, or are they successful in using the BLE library to bond from the central device?

Thanks for any guidance.

Cheers,

-C

  • Hello ,

    Let me answer your question, at least from the mobile apps developer perspective.

    Let's start with iOS. The only way to bond on iOS is by trying to read or write protected characteristic of descriptor, so if you ever plan to support that OS, your device and pairing procedure should support it.

    On all versions of Android, as far as I know, there's a bug related to bonding. The issue is, that Android allows unencrypted link despite having valid bond information. Moreover, the only API to check bond state returns only whether this information is present, not if it's used. So you may be connected to a device, the app may say that you're bonded (getBondState()), but link is completely insecure.

    Then, you have to imagine an intruder and what he/she can do. 

    Let's say you bonded to a device, which has some protected characteristics. You can read and write, as the link is secure. Then you disconnect, and the intruder starts advertising with the same packet as your device does. So them, when you connect, instead of connecting to the read device, you connect to the specially prepared intruder's one. You app has no clue about it. It says that the bond state is bonded, MAC address is ok. You have no idea whether the connected device is the right one, unless the device has some LEDs or makes a sound and the user noticed that the LEDs are now turned off. With no such blinking flashlights, you may send some sensitive information to the intruder using completely unsecured link, and your app will tell you that everything is OK.

    In the BLE Library there's "ensureBond" method, which removes bond information from the phone and bonds again, to make sure the link is encrypted. However, even if you use the "ensureBond" request from BLE Library, it would just remove the bond information, and recreate bonding with intruder. Again, if user won't notice lack of blinking LEDs, or won't read the info on the phone to check if the device behaves in some way, your phone will bond to intruder's device.

    If your device is e.g. a lock, and you make it work with "ensureBond" (so you will remove bond info when an unbonded device connects), then any intruder can just connect and bond and unlock anything. If you allow only a single bonding, and do not allow unpaired device to connect, intruder won't be able to connect and unlock, but intruder will be able to "emulate" the lock (with no encryption), or, I think can be able to replace your bonding information with some other, when the intruder's device would advertise as the real lock, and would trigger another bonding procedure, e.g. by setting protection level on its characteristics. With "just works" that would be invisible for the user on many phones, as there's no any pairing dialog.

    I didn't try to replicate all off the above, but I'm able to reconnect to HRM sample from nRF5 SDK after removing bond information from it, with the phone saying bond state is bonded. The rest has been deducted from this fact.

    The only reliable way of ensuring trust when connecting to Android is by building application-level security, where you build the encryption on both sides in your apps. Assuming no keys can be obtained from your app or your db on the phone.

  • Thanks Aleksander for the comprehensive reply. 

    I should add that I understand that devices must be bonded to be able to successfully reconnect given the presence then of a stable MAC address. Do I have this correct?

    If so then I’m still interested to learn how most central Android devices should go about bonding. Thanks. 

  • Bonded devices may use private resolvable address, which seems random and changes in time, but the central can assume that it's the bonded device that advertises, as its generated based on the shared keys. It may be that some random device would use an address that matches, but that's not very likely and still resuming bonding would fail if it wasn't the one. However, as I wrote above, in my opinion Android would not disconnect in such case, but would remain connected with unencrypted link giving no hint that it is not the same device that was bonded. I would really like someone corrected me here. I'll try to replicate and verify that today. 

  • Thanks again Aleksander.

    I'm really just trying to determine whether bonding is required for auto-connect to work over a long period of time. If yes, then what's the best approach to bonding on Android with the BLE library.

    Apologies if I've not been clear.

  • Thanks Emil. So, given bonding is required for reconnecting over a long period, how do most go about bonding using the BLE library? Do they use the ensureBonding call (which I’m still unsure of how/where it should be used) or do they rely on the user navigating to the system settings and doing it there?

Related