Is there support for secure pairing & bonding, e.g. with OOB secret ? If so is there an example ?



  • Our device works currently with SweetBlue in unauthenticated mode. We now want to implement security so that anyone will not be able to change settings. Security will be based on a shared secret, so specifying BLE OOB in the BLE pairing request seems like the obvious choise.
    However a scan to the FAQ and Javadoc for OOB didn't yield any result. Is this supported and if so is there an example ? If not supported what else is recommended to secure BLE access to our device (based on recent Nordic chipset, then moving to ST WB55).



  • Olivier,

    I don't believe you can do it with Android. There is a private method called createBondOutOfBand() in the android sdk, but that method is now protected in android 9+, and you can't call it (even via reflection). It seems with this method, the secret is transmitted in the clear, and you're using 1 secret for all connections. After speaking with some people smarter than myself, I would suggest implementing your own encryption scheme using something like a Diffie-Hellman key exchange .



  • I think for this authentication based on shared password, we could call PAIRING_VARIANT_PIN or PAIRING_VARIANT_PIN_16_DIGITS on Android side (https://developer.android.com/reference/com/google/android/things/bluetooth/PairingParams), which both expect the other device has displayed the pin for us. In our specific device case, it has no display but we have an API call that can provide Android app with the expected key.
    Then after receiving the onPairingInitiated callback, I think we can call finishPairing(BluetoothDevice, String) (https://developer.android.com/reference/com/google/android/things/bluetooth/BluetoothConnectionManager#finishPairing(android.bluetooth.BluetoothDevice, java.lang.String) after obtaining the pin from the api for finalize the pairing.
    Can you confirm whether this is a viable alternative to OOB. In the above I referred tot he native android API, not sure what the equivalent wrapping API methods of Sweetblue would be to achieved the same (for pairing only, and pairing & bonding as we need both variants for our use case)

    Android example for pairing & bonding :
    IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
    intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
    registerReceiver(broadCastReceiver,intentFilter);

    String BLE_PIN = "1234"private BroadcastReceiver broadCastReceiver = new BroadcastReceiver() {
    @Overridepublic void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if(BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action))
    {
    BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    bluetoothDevice.setPin(BLE_PIN.getBytes());
    Log.e(TAG,"Auto-entering pin: " + BLE_PIN);
    bluetoothDevice.createBond();
    Log.e(TAG,"pin entered and request sent...");
    }
    }
    };



  • I must admit, I'm not as familiar with that method of pairing. Usually you just call the bond method, and then a dialog will pop up requesting the pin.

    However, I would suggest that since you seem to have control over the firmware of the product, to implement your own encryption scheme. Android's pairing process can work well on some phones, but on others it can be a nightmare.

    I'd look into using a couple of characteristics for transmitting and receiving encrypted data. You can set up some kind of key exchange between the 2 to establish a session secret to use for encrypting/decrypting data.

    Easiest way would be to just implement pairing the standard way, and just call bond() to do so (but you will run into bonding issues on some phones).