I'm trying to make a BLE device that actually pairs securely. I posted this question on StackOverflow but didn't get any answers - maybe someone here knows more. As far as I know the transport encryption (using AES) is secure in all versions of BLE, once the 'Long Term Key' has been exchanged. This question is just about pairing.
BLE 4.1 and earlier use symmetric cryptography and the passkey (PIN) is only 6 digits so it is trivial to passively eavesdrop on the pairing, brute-force the passkey and derive the LTK from that. It seems that this was insecure by design because it was thought that low power BLE devices wouldn't have enough oomph to do asymmetric cryptography.
BLE 4.2 adds 'Secure Connections'. This is apparently also broken and what's more it was broken in 2008 when the same pairing method was used in Bluetooth 2.1!! It doesn't totally break pairing - only the passkey entry method - and you only learn the passkey, not the LTK. But it does allow an attacker to perform a MitM attack if the passkey isn't changed for every pairing attempt.
The Out-of-Band pairing method would be an excellent choice, then I can use a QR code or something. However there are no public APIs to access the OOB method on either Android or iOS. Android supports OOB pairing via NFC but iOS doesn't, so that's out.
It seems the only option left is to implement a custom encryption scheme, but that is a ridiculous amount of work.
Why did the Bluetooth SIG specify a pairing method in BLE 4.2 that was already known to be insecure 6 years earlier?
Are there any existing encryption schemes for BLE that secure it? Ideally open source and well-tested, but could be commercial. Would I still be able to use GATT?
Will Bluetooth 5 fix this mess?
Your questions should be best fit for BluetoothSIG, as we are not the sole party who define BLE spec.
Here is my opinion on your questions:
I understand that in many applications, the devices don't have IO capability, and have to use static passkey such as a number printed on the device/package.
If the attacker has physical access to the device, then this pairing can be compare to the same level as JustWork.
If the attacker doesn't have physical access to the device to get the passkey he need to do brute force or eavesdrop the pairing process of the authenticated device.
For brute force, since 4.2, we introduced the repeated request-confirm for each bit of the passkey, the attacker need to try 2^20 times, and each time he uses the wrong bit the pairing process will be terminated. So you can implement a check on the device to refuse pairing after let's say 3 consecutive fails for example.
For eavesdropping, since we use ECDH keys, the public and private pair are required, and I don't think it's easy to inject the attacker Public key based on a recorded session of the pairing process earlier.
Anyway, using static passkey is not recommended and for sure will reduce the authentication level of the process.
2.You can implement another encrypting layer on application, but this require you to find a secure way to exchange the keys, or hardcode and secure the keys on both peers. We don't have an example/suggestion for this.
3.We can't comment on specifications that are not adopted.
This still doesn't really answer the question of why they kept a protocol that is so fatally flawed (and could be fixed!). A fixed pin could be secure if the protocol were different.
@Tim: as I mentioned, BluetoothSIG is the best to answer questions regarding the spec. Please send requests and questions in their portal. You can join the SIG as an adopted member, it's free.