I have some questions about pairing Bluetooth.
Is there any events that can help me to get the pair authentication status? (e.g. after typed-password, authenticate success, authenticate fail, etc…)
Is there any properties I can use to get the pair authentication status? (if question 1 has no solution) (e.g. paired, unpaired, paring)
How can I remove the Bluetooth authorize programmatically? (it means when I remove the authorize, I will re-type password to pair my device)
Pairing in Core Bluetooth is initiated when you attempt to read (or write) a characteristic that has an encryption-required property.
Once pairing is complete you will be able to read (or write) the characteristic. If pairing is cancelled or does not complete then you will not be able to read/write the characteristic.
Pairing status can be inferred from the availability of the encrypted characteristic data
There is no way to remove the pairing programatically - It must be done by the user in the Bluetooth Settings.
Related
We are developing an iOS app that must pair (and bond) with a BLE peripheral before our app can proceed with other steps. From what I understand Apple wants accessories to follow this flow to initiate pairing:
iOS device connects to accessory
iOS device attempts to access an attribute that requires special permissions (e.g. authenticated connection or encrypted connection)
Accessory rejects the attribute access with an “Insufficient Authentication” error code
iOS realizes it needs to initiate pairing, so it generates a pairing popup that allows the user to initiate it
The problem is that the firmware on our BLE peripheral can not be altered. All of its BLE attributes are unprotected and do not require an encrypted or authenticated connection to access these attributes. So in this case, how can we get iOS to generate the pairing popup so that the user will have the ability to pair?
I realize that my question is related to How to bond/pair to a bluetooth LE device programmatically in swift Xcode?, but it differs in that we can not change the permissions used by the characteristics of our BLE peripheral. We have no control over the firmware.
Thanks in advance.
In my BLE app, the user story is like, bluetooth pairing should happen without the passcode confirmation step. As far as i have researched so far, it is possible in Android (like Android Bluetooth Pairing without User Enter Pin and Confirmation Using Android API)
Is it possible in iPhone?
Sadly, on iOS it is not possible to skip the pairing dialog. It is directly sent from the OS. It is a strict convention from apple that apps are not able to skip security processes.
Some additional information:
Dependent on the IOCapabilityResponse from the peripheral device on bluetooth level iOS will show you a dialog asking to pair or to confirm a pass code. If iOS will show you the dialog at all depends if the bondable flag is set in the IOCapabilityResponse from the peripheral.
There are three types of connection in BLE:
connection: pin not required, connection not secure
pair: pin could be requested or not, connection secured with short term key, a popup will be displayed
bond: pin could be requested or not, connection secured with long term
key, a popup will be displayed
All of these method are managed by BLE peripheral firmware, iOS only adapts its connection based on how the peripheral is configured
I want to avoid the BLE pairing pop up window on iOS when connecting to a small disposable device. The device will only be used once. If the device is advertising for its lifetime (no more than a few minutes) and does not require encrypted communication. Will an app that I develop be able to directly communicate with the device without displaying a pairing popup?
The pairing pop up is only shown if a characteristic specifies that encryption is required. If no encryption is specified by the peripheral then no pairing dialog is shown.
If you aren't getting the behaviour you desire, you need to change your peripheral or not access the encrypted characteristic from your central.
If you pair the devices, then the user must accept that. But if you just connect and communicate with GATT characteristics that don't need pairing, you don't need to pair and hence no popup.
How to force iPhone to pair to unpaired peripheral when peripheral has the pairing information.
There is no API for responding to the bonding process in Core Bluetooth.
If the peripheral doesn't require encryption then pairing will happen automatically when the iOS device connects to the peripheral.
If an attribute requires encryption then a pairing (actually bonding) dialog will be shown to the user by iOS when your app attempts to read/write the encrypted data. At this point the user will need to enter the PIN. There is no API that allows your app to complete the bonding without user intervention.
I want only trusted devices to connect to my peripheral. And I don't want anyone to be able to discover services and characteristics of my peripheral.
So before connecting to the peripheral I would like to show an alert with a pin code. Is it possible to do it and what is the easiest way?
I couldn't find the answer to this question and tried to implement encrypted characteristic by adding CBAttributePermissionsWriteEncryptionRequired to the permissions:
self.characteristic = [[CBMutableCharacteristic alloc] initWithType:[JUUIDBuilder uuidWith:#"1706"]
properties: CBCharacteristicPropertyWrite
value:nil permissions:CBAttributePermissionsWriteEncryptionRequired];
For some reason it didn't help because I'm able to write values from my second device all the time without any security checks. (Documentation for CBAttributePermissionsReadEncryptionRequired says:
...the characteristic is configured to allow only trusted devices to read or subscribe to its value. When a connected, remote central tries to read or subscribe to this characteristic’s value, Core Bluetooth tries to pair your local peripheral with the central to create a secure connection.
which doesn't make sense to me. What is "trusted devices" here?
Can anyone help me? What is the best practice to allow connections only from trusted devices with pin code confirmation?
You cannot prevent services and characteristics being discovered. You can advertise a primary service and have secondary services that aren't advertised, but once a connection is made all services and characteristics will be revealed.
If you specify that an attribute requires encryption, then a pairing (technically bonding) process will be initiated when you first try to read/write the characteristic. This process exchanges encryption keys and results in the devices 'trusting' each other.
If your peripheral and central are both iOS8 devices, then I have found that if both devices are configured with the same iCloud account then the trust is already established (presumably for functions such handoff) and you will never see the pairing dialog. This caused me quite a bit of confusion when I was trying to test encrypted characteristics.
If you test using devices with different iCloud accounts then you should see the pairing dialog.
Even the pairing process will not "protect" your service/characteristic if the "attacker" has control of both devices as they can simply complete the pairing process. Pairing/bonding does protect the data against eavesdropping as the transfer will be encrypted.
To actually protect the service you would need some form of challenge/response involving a characteristic before exposing data.
For example the central needs to read a value from characteristic "A" which is set at random by the peripheral. The central then needs to calculate the correct response to that value and write it back to "A". Only if this value is correct does the peripheral set values on the remaining characteristics (or accept inputs on the other characteristics from the central).
This solution is only secure as long as your challenge/response mechanism isn't compromised but will probably defeat non-determined attackers.