BLE Paring without bonding on Android - android

I have a couple of peripherals to which my android phone should be able to connect to. To secure the link I've implemented BLE-Secure Connections on the peripherals.
Since the only thing I want is to encrypt the link and I don't want users to have all my peripherals in their list of bonded devices, I don't want to bond.
So is it possible to just pair with the device and forget about it after disconnecting (and don't have to fear about some Bonding-Request dialog)?
Some background informations:
The Bluetooth Specification (v4.2 and v5) tells me, that Bonding or just Paring (throwing the keys away after the connection) should be just as simple as a Flag that one can set and request Bonding or not. (And on my peripherals this is that simple).
I already know, that I can pair + bond my devices with BluetoothDevice.createBond(), which nicely bonds in the background without any nasty dialog.

If you set the bonding flag to 0 on your peripheral and io capability to no input no output, then Just Works pairing will be done (no dialog). I also guess Android will respect the bonding flag you set on your peripheral and don't store the device info in the bonding list, since otherwise it doesn't follow the specification. The createBond method is still the one you should call.
The security you get in this case is just a simple Diffie-Hellman exchange, i.e. secure against eavesdroppers but not to a man in the middle.

Related

Can I have an encrypted BLE connection without bonding? / Pairing BLE devices without bonding

So far I am able to do things two different ways.
I can advertise a service on the Pi, connect from an Android app, and read/write characteristics. From my understanding, this communication is not encrypted.
I have been able to do the same thing adding pairing and bonding to the mix. I advertise a service on the Pi with an agent, connect from an Android app, and as soon as I try to read/write a characteristic I get a prompt on my phone asking to pair. From my understanding, after pairing is succesful the communication is encrypted.
That last part is great. However, I am looking to pair without bonding, mainly because I don't want to end up with a huge list of devices on my bluetooth settings. Android seems to use this term interchangeably, which just makes everything more confusing.
I know it's possible to do it as per this video. I just haven't figured out how to actually do it myself.
Any help is appreciated.
This is totally possible according to the Bluetooth protocol specification. If at least one device sets "bonding flags" to "no bonding" in the AuthReq field of the Pairing Request or Pairing Response, no bonding information shall be permanently stored.
If you're using BlueZ, I'm not sure if it allows you to configure this though.
For Android, people report that Android does not respect this flag and creates a bond anyway (Why does Android bond even when asked not to bond?).
Technically speaking, pairing is the process of exchanging the keys with a remote device, while bonding is the process of storing these keys. Some devices use the terminology "pairing" to indicate the the keys are exchanged and the connection is encrypted, but the keys will not be stored for future use. On Android this is not possible as far as I'm aware, and you always need to store the keys. This can be seen in the link below (see the section Bonding with a BLE Device):-
The Ultimate Guide to Android BLE
Some other useful links:-
Android BluetoothDevice API
Should One Create a Bond with a BLE Device
BLE Pairing and Bonding

Is Bonding required for BLE <-> Android, iOS device communication?

We have a BLE device and android/ios app for communication with the device.
The requirement is to have an android/ios app connect to the device without any pairing request. No security is required on the device.
Hereafter a few questions around this:
Q1. Is it possible at all to have an android/ios app connect to a BLE
device without a pairing request?
Q2. Does the bonding required for
the BLE communication?
Q3. What is the downside of having the device
with no bonding? Is it going to drop the connection while the app is
running?
Q4. Who is the initiator or pairing dialog, the app, or the
device?
Q5. When having the device with Just Works security protocol,
with no bonding and no MITM protection, should we see a pairing
dialog?
Please see answers to your questions below:-
A1. Yes it is possible to do this because pairing and connection are two separate actions. Connection is when you establish a communication channel with a remote device, while pairing is when you exchange security keys with the device and have the option of encrypting that connection.
A2. No, pairing/bonding is not required for BLE communication but it is preferred in order to have extra features and extra security on that connection.
A3. No, having no bonding does not affect the stability of your connection/communication. There are a few downsides which include less security on the connection and also potential inability to find the device if privacy is implemented. More details are provided in the link below.
A4. The app is the initiator of the pairing dialog. Specifically, the central device (the one that initiates the connection) is the one that is responsible for initiating pairing. When this central device requests to pair to the remote device, the pairing dialog is shown.
A5. I believe this is dependent on the OS type (Android/iOS) and the version number of that OS, but generally speaking the pairing dialog should not pop up because as the name suggests, it should just work. Pairing dialog pops up when MITM protection is requested.
You can find more details about pairing/bonding and general BLE communication is the answer below:-
Should one create a bond with a Bluetooth LE device
I would also recommend trying the nRF Connect app on both iOS and Android to see the difference between connection and bonding and to verify that you can have normal connections without pairing.
Based on what we got working and based on the answers to this question.
A1: Yes, it's possible if no MITM is set and the Security scheme is set to Just Works, which means no security at all.
A2: Bonding is not required for BLE communication. If the BLE device can't store the Bond information, it may lead to some issues as we got in our case. If the BLE device is able to store and use Bond information then it's recommended to Bond.
A3: The Connection will not be closed. The only downside we got is that now it takes a little more time to reconnect.
A4: The app is initiating the connection, but the dialog is shown only if the BLE device requests some type of security, it can be MITM, encryption, pin. Short answer, the pairing dialog can be avoided by changing the settings on the BLE device.
A5: When having the device with Just Works security protocol, with no bonding and no MITM protection the pairing dialog should not be presented. We got no pairing dialog experience on both iOS and Android.
To add to Youssif's answer:
A3: one difference is that connection setup will be faster since bonding allows the GATT db cache to be used. Otherwise service rediscovery must be done on every connection (if the service changed characteristic is present).
A4: on Android you can call createBond to start pairing, but on iOS there is no API for the security, so either you need to interact with a characteristic that sends an error that pairing is needed, or the remote device can send a Security Request to initiate pairing.
A5: iOS shows a dialog "accept / abort" for just works, Android doesn't.

Android Things BLE peripheral encrypted write and read permissions

There isn't much documentation in regards to setting up a pin with a Bluetooth Low Energy peripheral device. In my Gatt service I have set the BluetoothGattCharacteristic.PERMISSION_WRITE_ENCRYPTED_MITM and receive a GATT_INSUFFICIENT_PERMISSION message in my log upon attempting to write to the Bluetooth Write Characteristic I have set up. I was wondering what the process is for enabling encryption for the peripheral.
Thanks
Bluetooth LE requires to devices to be bonded (paired) before they can successfully encrypt transmissions used to read/write a given characteristic. Android does not handle this process for you, so you will need to initiate pairing between the two devices before any GATT transactions are attempted.
With the current Android Things previews, development of the Settings app (which generally handles much of the device pairing process) is heavily in flux. As such, traditional workflows for pairing a device are likely not to work at the moment until these changes are complete.
You could try initiating a pairing request from your Android Things device via createBond(), listening to the ACTION_PAIRING_REQUEST broadcast, and applying the necessary PIN code with setPin(). Some combination of those may work for you in the short term until a more official solution is available.

Android Bluetooth Low Energy Pairign

I'm a little bit confused with BLE. I read that the BLE pairing process has three options and the one I'm interested in is the Passkey Entry.
My goal is to have a sensor on the field and the Android App will scan and find this sensor then it will request to pair with the sensor before they can exchange data. The user app is either running on a cell phone or tablet.
Is the BLE pairing the same as Bluetooth Classic? I mean is the Android API BluetoothDevice.setPin used for both BLE and Classic and the driver will do the rest under the hood?
I'm confused because I read somewhere that for BLE I can set a PIN or a Passphrase but BT Classic only accepts a 4 digit PIN.
Pairing in BLE is just a way of setting up an encrypted link. The devices need to agree on an encryption key and they do this either by just works (which set the key to all zeroes), passkey entry (up to six digits) or out of band (keys distributed over NFC or some other channel).
If you use passkey that means a "snooper" cannot pair with your sensor unless he can see the pass key on the device. (Either printed or on a display)
You can also combine a pairing with bonding where the devices distribute keys after encrypting the link making it possible to reconnect with the same device without having to renter a key.
You then want to set up your database on the sensor to only allow reading the sensor data over an encrypted link. (You don't want your snooper to simple connect to the device and read out the data himself).
The one problem with this approach is that the pass key entry only uses 6 digits. That is not enough entropy to really protect you against someone eavesdropping. The key generated after a passkey entry can be brute forced in milliseconds and all the commercial Bluetooth sniffers does this as part of their normal operation. They do however have to sniff the pairing procedure to do this, so if nobody was eavesdropping when the devices was bonded your usually good.
Also using out of band data is safe, since you cannot easily brute force a random 128 bit AES key.
A PIN type of passkey is not used in BTLE as far as I understand the specification. Legacy Bluetooth devices used a fixed PIN passkey that was hardcoded into the device or entered by the application. This method of pairing was replaced by SSP (Secure Simple Pairing) in the next round of Bluetooth. BTLE came later and uses only SSP. The passkeys in SSP (when man-in-the-middle protection is enabled) are generated randomly by the Bluetooth software usually at pretty low levels. One SSP option is 'just works' and the entire passkey generation is internal. Great for the user but it is possible for Man-In-The-Middle (MITM) attacks. So in the end, for your Bluetooth LE application you will never use the 4-digit PIN.
So pairing with BTLE devices on the Android can be done in exactly the same way as one pairs standard Bluetooth devices. If the BTLE device is using an SSP option beyond 'just works', you will get a popup menu asking for you to either
verify a number displayed on the device and/or provide a number
that you must verify on the device (yes-no and display-only combos)
require that you enter a number that it displayed on the device
and/or display a number that you must enter on the device (keyboard)
The built-in pairing feature works for both BTLE and BT devices in spite of the fact under the hood the mechanisms are very different. BTLE devices transmit advertisements that client devices scan for (BTLE 'discovery') whereas BT devices scan for transmissions from the client (BT discovery) when it is looking for devices.
Alternatively one can use the BluetoothAdapter.startLeScan(LeScanCallback callback) method to scan for BTLE-only devices. This method will give you a list of BTLE devices that one can then select and attempt to connect to. In this scenario, your application will need to take care of pairing when it is required. Usually pairing is not required on BTLE devices until one attempts to enable notifications or indications. Service discovery, reading the Device Information Service and other tidbits often do not require pairing and if memory serves me right one can never require pairing for service discovery.
So to make life easier for my application I link to the standard Android provided tool for the discovery/pairing of any device that requires pairing and for those BTLE devices that do not require pairing (and there are a number of such devices) I use the startLeScan() APIs and do a BluetoothDevice.connectGatt() to one of the 'discovered' devices. If I use this approach and the device actually requires pairing I will get a security error. In theory I should be able to use the pairing APIs provided by Android to then pair with the device. Unfortunately my inept programming skills have led to the fact that I have yet to succeed in implementing it correctly.

Is there a way for automatic/programatic pairing of 2 bluetooth devices in android?

I am developing an application which connects devices over bluetooth and exchanges messages. It works fine for paired devices, but I would also like it to automatically pair devices that are not paired. Like for example it could store and use the same PIN for pairing requests, I just dont know how to manage this request programatically in my applciation, how to automatically set and send the PIN when you get a pairing request and how to initiate such a request with the predefined PIN code.
Any snippets or thoughts would be highly appreciated! :)
EDIT:
I know its risky, I am developing this app for emergency situations only where no other means but bluetooth is available. Also is there maybe a way of premature pairing with devices without even connecting to them? Like lets say there is a list of MAC Addresses of those devices and I can use them to generate a bond with that devices so that they appear paired on my device?
You can't do this. To do what you want to do would create a huge security risk. Think about it, my device just comes anywhere in bluetooth range of yours and now I can send you anything I want without you knowing? You can't really do this and I highly recommend not trying to subvert it.
Reflecting the setPin method allowed me to send the pin automatically to the other device. I had to implement it in a broadcast receiver that is listening for pairing requests. Although I cant get rid of the dialog it just stucks there on the screen and I dont know how to close it (programatically) and continue the bonding procedure since this dialog is called from inside connect() which is a blocking method. I am not giving up on it yet though :)
With Bluetooth version 2.1 and above there is a method of pairing called the 'just works' association model. This is the lowest security method of pairing and has no protection against man-in-the-middle attacks.
However, this will provide a secure, encrypted link without the need to exchange pin numbers or verify device ID.
The API on different platforms may differ but the underlying HCI messages require that you indicate that your device (or one of the devices) has the following IO capabilities:
No Keyboard, No Display.
As you might have guessed, this is a mode for very
simple devices that use Bluetooth, such as a speaker or headphones.
If you can find the API to configure that, then the 'just works' association mode of Secure Simple Pairing will be used for pairing.
The next step is to store the link keys e.g. bonding. Many devices e.g. mobile phones, will still create a dialogue box to the user to ask if they want to 'remember this device', as user authorisation is specified by the BT specifications... but that's another problem.

Categories

Resources