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.
Related
I have MFi device which uses BLE for control and Classic Bluetooth for audio streaming.
In the App, i use coreBluetooth framework to scan BLE and EAAccessory framework to scan Classic Bluetooth.
I don't want the BLE of target device to be connected if its Classic Bluetooth is not yet connected. So i need to know which EAAccessory is corresponding to target CBPeripheral.
I am familiar with coreBluetooth, there is UUID string to identify the CBPeripheral. But it looks not exist in EAAccessory.
I have an idea but not sure: maybe firmware side can config EAAccessory's serial number and CBPeripheral's manufacture data in advertisement data with the same
serial number, so that App side can check if they are the same.
Dose anyone knows the general way to implement this in App side and firmware side?
I really do not think there is s relationship between the 2. BT and BTLE are managed by different chip at peripheral side and phone side.
Usually in BT you use the MAC address to identify the peripheral on BTLE side the MAC address is not used anymore since iOS at the first connection give its own identifier to the peripheral.
What you can do is probably at firmware side, by exposing a service with a characteristic that somehow relate the 2.
UPDATE AFTER COMMENT
I see, as far as I know there a best practice doesn't exist.The worst part is that you have to handle connections differently, mostly due to how connection are made on iOS side. While on the BLE you can choose a not encrypted connection that would not require paring or bonding, on BT side I guess that bonding is required.
Probably the most simple flow would be, user bond the BT device. Once you are in the app and detect the connected BT device, use a scan method for detect BLE companion device by filtering for a specific service id that your device exposes, once you do that you can also filter discoveries using BLE name without still making a connection.
Adv packet are restricted in size (29 usable byte) but you can also use the scan response (31 byte), that exposes some additional properties such as manufacturer data that will be exposed in a dictionary (kCBAdvDataManufacturerData).
Once you know that is the correct device you can start a connection, that does not require pair or bond but is NOT encrypted (Pair and Bond will require the user to accept the connection inside your app).
I'm working on an application that connects phones via core bluetooth (BLE). The connection and data transmission work beautifully, but there is one small imperfection. When connecting to a new device, a pin must be entered on one of the devices. The application is supposed to be very instantaneous, and the pin-input greatly interrupts this process. I'm not worried about security, and I've personally connected my phone to many bluetooth devices without entering pins, so I was just wondering how this could be done with the iOS api.
Thanks!
If you specify any of your peripheral's characteristics with an 'encryptionRequired' property (CBCharacteristicPropertyNotifyEncryptionRequired or CBCharacteristicPropertyIndicateEncryptionRequired) or permissions (CBAttributePermissionsReadEncryptionRequired or CBAttributePermissionsWriteEncryptionRequired) then bonding is required between the devices.
If the devices aren't already bonded then this will trigger the pairing dialog and require a pin to be entered. If you don't specify any of the encryption properties or permissions on your peripheral's characteristics then you won't be prompted to pair.
Can someone suggest if it is possible in BLE communication to authenticate the central from peripherial before connection is established?
Example:
1) Peripherial Advertises continuously
2) Central discovers Peripherial and sends connection request
3) Connection is Established and Advertising stops
3) Peripherial authenticates central via AES or Pairing etc.
4) If authentication is succesful transfer data.
Either ways once this malicious central has connected to peripherial the Genuine Central will not be able to as each peripherial. If I have understood properly, Peripherial can not end connection or start connection and peripherial do not allow simultaneous connections.
How can I solve this problem? Even if some way of terminating connection from peripherial is made possible, the malicious central will keep reconnecting hence essentially performing DENIAL OF SERVICE(DOS) attack.
Thank You!
You have the sequence slightly wrong. It should be -
Peripheral advertises
Central discovers peripheral and attempts to connect
PIN is requested if central is not already paired
Connection completes if pairing is successful. If not return to state 1
If connection is successful advertising stops and data can be transferred.
So, the security is based on the PIN being kept a secret. If the PIN is well-known (i.e. defaults to 0000) or can be easily discovered (printed/displayed on the device and physical access is possible) then security is compromised.
In theory a DOS attack is also possible by making repeated connection attempts, but this does still leave an opportunity for the legitimate central to connect.
Okay, this is a little late, but anyway: from v515 upwards you can use the AT+TYPEx command to change the authentication behaviour.
x can be, according to the docs:
0:Not need PIN Code (default)
1:Auth not need PIN
2:Auth with PIN
3:Auth and bond
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.
Following off of this question:
Corebluetooth, How to get a unique UUID?
After connecting to a peripheral, I can retrieve its CFUUIDRef, which is unique, and can use it to reconnect via retrievePeripherals. However, I have found that I can not use it to reconnect after closing the application.
Is the unique UUID generated after a connection only valid for the lifetime of the application or are we supposed to be able to save it for later use? I am trying to have my application remember one particular peripheral, but besides peripheral.UUID, I don't know of any other unique identifiers.
Long story short, YES you can use the UUID to reconnect to the same device even after you close the application (in exactly the way you say).
I assume however, that you are not actually pairing with peripheral. That's a big problem right there. You need to actually establish the pairing request and get the peripheral to show up in the bluetooth table. The UUID will then be solidified with the iOS device and will remain until you flush the Network Settings of the iOS device.
The other possibility is that your BLE device has a firmware problem, wherein after you disconnect, it forces itself into advertising mode or something. This will also mess with your ability to reconnect. Let me know if you have any questions!