We are working on a project of developing the soft and hardware for a bluetooth LE device.
We implemented GATT services and we are able to connect to the device.
Now the next step: Implement security.
We know that there are tree methods of security:
Just Works
Passkey Entry
Out Of Band
Since our device doesn't have a display (no_input, no_output), we are doomed to use Just Works since OOB is not supported by Android and iOS yet.
So this means we have this bluetooth device with all it's services just hanging there in the open to connect by anybody.
Is this really true in BLE?
We were thinking about implementing our own security just by connecting, writing a key to a keyservice and when that key is correct, the services open themselves for writing/reading. But what would that do with certification?
So you guys are our last resort since we are still hoping we are wrong in this one. Is there anybody who can acknowledge this fact? Or are we missing a big piece of the puzzle?
You can implement Just Works, Passkey Entry and Out Of Band (NFC) on your BLE Device.
Passkey can be written on a label on the product or be hardcoded to 0000 or 1234 or whatever you choose. This works on iOS and Android if you implement correct Bluetooth Security configuration on your BLE Device. What chipset are you using?
Out of Band works fine on Android and Windows Phone with NFC. Maybe Apple iPhone 6 and 6+ will get proper NFC functionality in a more mature iOS version later. On iOS 8.1 it is still just for Apple Pay, not for industri standard NFC functionality.
First step is to set the GATT flags so your Service or Characteristic requires security.
Second step is to implement the bluetooth Security manager messages.
There are official white papers on this on BT Special Interest Group:
https://developer.bluetooth.org/DevelopmentResources/Pages/White-Papers.aspx
Related
I'm studying the Bluetooth Low Energy (BLE) protocol (v4.2), and in particular its security features.
I'm trying to understand how the encryption of data transmitted between a mobile App and a BLE device works.
The official documentation (v4.2) specifies the methods to encrypt data, authenticate the devices, generate the keys used in the encryption and pairing phase, etc..
First doubt (I want to be sure to have understood some concepts):
all these functions are implemented in the host level, so if I want to encrypt data transmitted between an App (Android) and a BLE device (like a fitness tracker),
do I have to implement (or enable) these methods on the BLE device?
In this way, the developer should only care about the implementation of these features on the BLE device, since the Android Bluetooth stack just support these features. Am I right?
If I'm wrong, what is the right way to implement these features (on both mobile app and BLE device)?
Second doubt:
Why some BLE devices, implement their own cryptography, on top the GATT protocol, instead using the security features provided by the SIG?
Third and last doubt:
Are the security features specified by the SIG mandatory or are optional?
As you can see I have some doubts, and maybe some questions could be silly, so if someone could clarify how the security mechanisms (like encryption) can be implemented between an App and a BLE device,
and at which levels these features are implemented (OS or application level), I will appreciate a lot.
If you use the standard BLE encryption, it is actually the link layer at the controller that does the encryption/decryption/verifying auth tags. But it's the host layer (SMP) that defines how two devices pair, bond and exchange keys. It's also that layer that tells the link layer to start encryption using the exchanged keys. On Android and iOS, it's the OS that manages the pairing and bonding and implements the SMP. Whether or not Bluetooth pairing/bonding/encryption is used is fully up to the device, and is optional. If it's not supported it must still support to send the error code "Pairing Not Supported"
The Bluetooth standard only has one "use case". This use case is to provide a method for securing the link between two devices so that, after bonding, no one should be able to impersonate a device or be able to manipulate or decrypt the traffic. As you might know, the "LE Legacy Pairing" which is the only pairing method specified up to Bluetooth v4.1, has several flaws that makes it unsecure if the attacker sniffs the traffic during pairing (both for "Just works" and "MITM/passkey entry", but not OOB). The new "LE Secure Connections" defined by Bluetooth v4.2 however uses Diffie Hellman to make it more secure.
Even though Bluetooth pairing itself provides security, there are some flaws in both the Android API and the iOS API that still may not be enough for an app developer if good security is needed. Notably, iOS does not provide any API whatsoever to detect if a given device is actually bonded or if a link is encrypted. It does however show a popup to the user when the pairing starts, but the app knows nothing about that pairing. So, from an iOS app's point of view, you don't know:
If you have paired to the device.
If you talk to a genuine device or a chinese copy.
The security level, i.e. if the pairing used Just Works, MITM legacy pairing or LE Secure Connections.
If the current link is encrypted.
Android is a little bit better. There the app can at least know if the device is bonded or not (but not the other three). There is also an API "createBond" to start the bonding process. The Windows API is much better here, since you can enforce encrypted link when doing GATT operations.
Any of these reasons may be enough for a developer to implement the security from scratch on top of GATT instead. In particular one often common use case is that the developer wants the use case "log in to the peripheral" with a PIN or password. The Bluetooth standard does not support that use case in any way (and no, using "MITM protected pairing with static passkey" doesn't work, since that protocol by design reveals the passkey after one or a few tries).
Anyway, if you develop your own peripheral with your own hardware and want to use the Bluetooth standard's pairing/bonding/encryption, the SDKs by the manufacturers of the BLE chips have usually already implemented this. However, you still need to set it up correctly for it to work. Usually you only have to configure some parameters (like if you have a display or the user can enter a passkey) and then the rest is automatically handled internally by their SDK.
UPDATE:
Source code for Android can be found at https://android.googlesource.com/platform/system/bt/, https://android.googlesource.com/platform/packages/apps/Bluetooth/ and https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth.
I'm trying to demo android side service (content provider in ANCS lingo), that communicates with embedded device that supports Apple Notification Service (ANCS) notification consumer. Reason for this is, that the embedded device only supports ANCS. As the ANCS BLE side things are publiced by Apple, this should be possible and I've already added that service + associated characterics to android side gatt server. Embedded device is nordic nRF52 and SW is nordic ANCS demo. Demo works OK with iPhone and apparently with the desktop version of nRF control panel (if added with nordic supplied config and if you have windows machine, which I don't).
However I cannot seem to be able to bond the device with android, that's required before connection. The advertisement is in limited discovery mode (before bonding) so I cannot find it via regular scanning from settings. Also bonding from java code doesn't work. With mBluetoothDevice.createBond() I get ACTION_BOND_STATE_CHANGED callback with state 10 (BluetoothDevice.BOND_NONE) with old state 11(BluetoothDevice.BOND_BONDING). Apparently I would need to exchange keys here, but no idea how to do that.
Also dunno if anyone has done this same exercise before, but any other tips would also be appreciated! Thanks!
Problem was that the phone BLE stack was corrupted or in some invalid state. REboot and removing battery solved the issue with the bonding.
I'm developing an app to communicate with a BLE device (Sensor puck from Silicon labs) and get whatever it is broadcasting.
I have NO experience in developing any sort of Bluetooth application using Android.
Do I need to manually pair it to the BLE device? I downloaded Sensor puck app from Play store, it automatically started to read from the device. I don't understand how since I didn't pair it.
Do I need specific API to communicate with the device? Is it like, I connect to the device and unpack the data which the device is broadcasting?
Any other information related to BLE application development would help.
Thank you.
PS: I can't use the app from the play store as I need the data from the device for some other processing.
I have a little experience with developing BLE apps.
Do I need to manually pair it to the BLE device?
I haven't encountered use case where I needed to pair mobile device with BLE device. Basically, you can communicate with BLE devices without pairing with them. BLE devices constantly emit signals and you can read these signals. Usually, from the emitted signals, you can read name of the device (or producer name), MAC address, RSSI signal from which you can compute distance from your mobile device to BLE device. Some BLE devices emit other information like temperature read from their sensors, etc. You can read information from more than one BLE device during the single scan.
Do I need specific API to communicate with the device?
Google provides API, which you can use to communicate with BLE devices. You can read more about it at: http://developer.android.com/guide/topics/connectivity/bluetooth-le.html. You can also use some third-party libraries allowing to communicate with BLE devices. Most of them are dedicated to so called Beacons, which are simple, tiny BLE devices.
Exemplary APIs for BLE Beacons:
Estimote
Kontakt.io
AltBeacon
ReactiveBeacons - this is open-source project, which I'm currently developing, so if you have any questions regarding it, you can ask me directly
Other projects:
Android Bluetooth Demo - this is very good and simple project, which can help you to understand how to use BLE API provided in Android SDK
Other information:
To communicate with BLE devices, of course, you need to have Bluetooth enabled on your device, but regardless of this permission, you also need to have Location enabled on your device and added location permission to your app. I guess it's done due to the fact, that you can use BLE devices for creating micro-location services.
I gathered some references concerning BLE for myself. You can check them here: https://github.com/pwittchen/ReactiveBeacons#references and maybe they will be useful for you as well.
Regards,
Piotr
it might be too late, but it also might be helpful for other users. So Sensor Puck works like a simple beacon and it doesn't require any pairing. You just have to scan all bluetooth devices nerby and verify received ScanRecord object. You don't have to use any specific libs or API, Anroid sdk contain all necessary api for such case (please see BluetoothAdapter startScan, startLeScan, etc). Also you can find an example how to parse raw data in my demo project https://github.com/alexeyosminin/sensor_puck_demo
I'm trying to realize an Android-Beam-like behaviour between an Android Smartphone and a Linux Host. The Android Smartphone (Galaxy Note 3, Android 4.4.2) touches an NFC Dongle connected to the Linux Host and exchanges Bluetooth carrier data via NFC so it then can connect to a Bluetooth Dongle, also connected to the Linux host.
Now the problem is, that the Android Smartphone always asks the User (me) if I really want to pair with the Bluetooth Dongle. In Android Beam between two Android mobiles, this user confirmation doesn't show up, the user only has to click the content (i.e. the picture) to send it (and this is the behaviour I'm trying to get to). I'm using the "nfctool" to sniff the incoming Handshake Request message by the Android mobile (see http://pastebin.com/Dr0D0nqn ). According to the "Bluetooth Secure Simple Pairing Using NFC" document by the NFC Forum (see http://members.nfc-forum.org/resources/AppDocs/NFCForum_AD_BTSSP_1_0.pdf page 19) this Handshake Request should contain a Simple Pairing Hash and a Simple Pairing Randomizer, which are both missing in the Handshake Request by Android.
So my questions are:
First of all, is Android Beam using Secure Simple Pairing with OOB at all, or another mechanism? Why is the Android Beam between two Android devices working without confirmation of the pairing?
If it is using SSP, why are the SSP Hash and Randomizer missing in the HR message? Could this be the reason, why my pairing needs user confirmation?
If Android is using another mechanism, how do the HR messages roughly look like? Do they use a special type name (other than "application/vnd.bluetooth.ep.oob") or anything else in their Handshake Request, which circumvents the user confirmation of the BT pairing?
Are there any technical documentations (I couldn't find any so far) of Android Beam available? The NFC guide on android developers ( http://developer.android.com/guide/topics/connectivity/nfc/nfc.html ) isn't of much help concerning Android Beam.
Any help is much appreciated :)
I finally found the solution for this problem, and answers to most of my questions:
Yes, Android is using SSP, but Hash and Randimizer are not mandatory, so it's no must that they are included in the NDEF HR/HS messages.
Android is using HR messages with type name "application/vnd.bluetooth.ep.oob", this is correct.
It seems to be sufficient for SSP, if one device confirms the pairing process. So the solution for my problem is, to set the IO capabilities of the Linux Host to "DisplayYesNo" and then autoconfirm the authorization request. This way the Linux host fakes User input and the Android mobile wont ask the User for his confirmation anymore. A quick (and a bit dirty) way to realize this is to change BlueZs "simple-agent" script to confirm every authorization request.
I am a newbie working on bluetooth, and I would like to get some advice regarding the pairing process. I have googled this but I did not find much information ...
My goal is simple: I want to do a pairing to a headset without entering a pin. I have an android (nexus S running Android 4.1.2) and an iphone (3GS running ios 6.1.3).
If I connect to a device like a Jabra BT3030 (bluetooth headset), the pairing is performed without asking me any pin code.
Now I want to do the same from an Ubuntu (with BlueZ 4.6), i.e. I fake a bluetooth headset by enable only the correct service and so on. I disabled the authentication.
When I pair my iphone to this device, no pin code is required (as expected), but when I connect from my Android device, it still asks me for a pin code, whereas I would expect to have the same behavior than with the Jabra.
Would you have any idea of what I am missing here?
Thanks in advance,
Best regards,
Guillaume
Android Uses UUID for pairing and connection for two devices...for two devices conneting, one device should send request and one should accept and for both UUID should be same...
Like also used bluetooth there I need to intall my android app to both the devices then only I can pair the two devices...because only that app is knowing the UUID. and for iPhone it may be different so if from the native code of iOS u can know the UUID ur android device can be paired through app...
The Standard password for a Jabra BT3030 is 0000. Many other bluetooth devices have a standard password. For the Case a system only accepts devices with passwords, and u cant enter a pasword on a device without keys :D
Maybe the solution is implementing the standard passwords for mutliple devices and use them instead f forcing a connection without password.