Android Bluetooth Low Energy Pairign - android

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.

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

What is the difference between pairing with a bluetooth device vs connecting to a bluetooth device?

I am working on a Flutter app that connects to a bluetooth IOT device. I am using the flutter_blue library. This library allows for the scanning of nearby bluetooth devices. Based on that scan you can "connect" to a device. There is no concept of pairing to a device.
From my previous experience using bluetooth on my phone (when connecting to my car and my bluetooth speaker), I have to pair the device at the Android OS.
I am curious, from a high level, what are the differences between pairing a device vs connecting to a device. In addition, more specifically, what is the difference between pairing a device within the OS, vs scanning and connecting to the device from an app?
At a high level, you will always use "connect" to connect to a device, but you may have to "pair" the devices first. Bluetooth pairing is a security procedure. A one-off provisioning step that equips the two devices in a pairing with a series of shared security keys which allow communication to be encrypted.
A Bluetooth Low Energy device can have three levels of security, the lowest of which pairing is not required, and then two levels that require pairing.
A device opting to use No Pairing provides the greatest simplicity but obviously, no security. Communication is not encrypted and any other device can connect.
The two pairing method that can be used provide the same level of security when connected. However, during the pairing procedure itself, one of the two methods is more secure than the other.
Passkey Pairing is the most secure of the two procedures and requires a 6 digit number to be entered. This offers protection against machine-in-the-middle (MITM) attacks.
Just Works Pairing is not as secure but it does not require you to enter anything and therefore is very simple to use.
Once a pairing is established, then connection can happen without the need to establish pairing every time.
More detailed explanation of the pairing options are available at:
https://www.bluetooth.com/blog/bluetooth-pairing-part-1-pairing-feature-exchange/
According to the Bluetooth Core Specification Version 5.2 | Vol. 1, Part A, Chapter 5.1 pairing is defined as
the process for creating one or more shared secret keys
The keys themselves are not shared but established using a procedure called Diffie-Hellman key exchange. This means that pairing is only necessary if a connection is encrypted. If you connect to a device that requires security measures on one of its characteristics Android will prompt the user of your app with a pairing request automatically.
Another term you might have heard is bonding, which is defined as:
the act of storing the keys created during pairing for use in subsequent connections in order to form a trusted device pair
Bonding allows a reconnection of your devices without another pairing process since the keys have been established before.
When using Bluetooth Low Energy (BLE) pairing a Device manually within the OS is not needed. You can always scan for a device that advertises its presence. As I said before: Pairing is handled by the OS automatically if needed.

BLE Paring without bonding on 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.

Pre-pairing bluetooth devices

I would like to be able to pre-pair bluetooth devices, to save the step of user confusion when using the app. I have discovered that there is a patent for
System, method and apparatus for pre-pairing bluetooth enabled devices.
I am looking at pairing an array of android devices with an array of embedded devices, so when the android device is set up, I can pre-pair it with the devices it needs to communicate with. I have considered maintaining a list of MAC-addresses that can be downloaded and updated by the app.
Is there a way to pair two devices without having to bring them into contact?
My memory is not exact, it's a while ago I poked around in the Bluetooth stack, however, I don't think this is possible.
Basically there is a white list (text file pretty much) which is kept by the system with devices that may connect to your phone, in order to access that white list outside of the Bluetooth api you need to be platform manufacturer. The Bluetooth Api is strongly guarded (by the specification), if you don't fulfill it you can't say your device supports Bluetooth. Pairing is an important part of the Bluetooth security model, I doubt even an oem would be allowed to do this.
One thing you could look into are Bluetooth low energy devices, those don't require pairing prior to connection (you should be able to connect if you have the MAC address), only Bluetooth classic requires pairing.
More info:
https://developer.android.com/guide/topics/connectivity/bluetooth-le.html
No its not possible unless you make changes to the ROM.
If the use-case supports,you can have ble devices advertising data in a pre-defined format so that the app detect your devices.Once you have recognized your devices,you can internally send a pairing request.

Android Bluetooth Pairing

Can anybody tell me how to find out which pairing technique phone used while connecting to other device?
I have a Nexus S(Android 2.3.3) and a BT device(Bluetooth2.1+EDR).
When I try to pair them, I dont have to give any input(passkey). As both devices are having bluetooth 2.1, I want to know which pairing technique they used.
Can we specify the pairing technique to phone?
When both devices are 2.1 and above the Secure Simple pairing (SSP) gets used instead of the legacy pairing (legacy pairing is the one where user was required to enter same PIN on both devices to connect and most of the cases PIN used to be well known common combinations of 0000 or 1234)
Secure simple pairing simplifies the process and gets rid of the need for PINs to be entered, instead it generates 6 digit passkeys automatically as part of the pairing process and user may only be required to verify/enter the passkey on one or more of the devices.
Secure Simple Pairing (SSP) further has few different association modes and the association model to be used is determined by the display and input capabilities on the devices that are trying to pair.
When there is no display or input to enter 6 digits on one of the devices, then "Just works" association model gets used , in this the user input is not required during pairing. In Android it is possible to force this model is SPP applications when using the createInsecureRfcommSocketToServiceRecord() API. This model gets used commonly when pairing with Headsets, other small devices without any display or input capability
Other association models are :
Numeric Comparison - Where a 6 digit number is shown on both devices and user is asked to confirm is they are the same. Used when both devices has display and capable of entering Yes/No.
Passkey entry - When one of the devices has only input capability and no output display capability and the other has an output / display capability, here the user will be asked to enter the 6 digits on the input only capable device as shown on the display capable device.
Out-of-Band - Where devices exchange pairing information over a different channel (other than Bluetooth) example NFC or some other secure mechanism.
You can either sniff the Bluetooth traffic or take a log to figure out which technique is being used. On a Nexus-S $adb shell hcidump -XVt will show you the log. If I/O capabiltiies are being exchanged than its Bluetooth 2.1 pairing.
Another option is to enable bluetoothd log in init.herring.rc file and you can figure out which pairing method is used.
Its most definitely Bluetooth 2.1 pairing in your case and the problem is elsewhere.

Categories

Resources