This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Android application and Passkey

nrf52832.

SDK14.2

Segger ES V3.34a

This question is probably best suited to an android forum (possibly).

We have a characteristic which is writable. When written to the peripheral asks our in house application to enter the passkey.  The setting for the characteristic are:

BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&cus_init.brand_char_attr_md.cccd_write_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cus_init.brand_char_attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&cus_init.brand_char_attr_md.write_perm);

and Security setting...

#define SEC_PARAM_BOND 1 /**< Perform bonding. */
#define SEC_PARAM_MITM 1 /**< Man In The Middle protection not required. */
#define SEC_PARAM_LESC 0 /**< LE Secure Connections not enabled. */
#define SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */
#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_DISPLAY_ONLY /**< No I/O capabilities. */
#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */

This works great.  We only get prompted for the passkey when we try to write to it and the App auto populates the Passkey.

BUT.

On some Android phones/tablets there is a variation in how the Pairing Request is dealt with, sometimes it's in the task bar or pops up a window to enter the Passkey.

Are there any alternatives for 'write' protection or have experienced the same thing and found a fix or workaround in the Android App?

I have also noticed this with nRF Connect Application.  On my Samsung Tablet I get a popup with a keypad but on my Oneplus3 phone the pairing request is in the task bar.

I would appreciate anybody's  thoughts or ideas.

  • We don't want the user to have to enter any codes or even press OK ie no bonding. 

    I think this idea is good

    One option you can think of is to have an extra layer of security on top of Bluetooth pairing. For example, after each connection establishment, your characteristic would generate a random value. The app on the phone need to read this and write a correspondent (using a hardcoded secret key and the random value) value back to the characteristic.

    Not sure what you mean by 

    After that your device start to operate

    But what bout this idea?... if this process is not fulfilled within a timeout, the peripheral drops the connection. But as we don't want the user interaction on the App (no bonding) we can't have any security on the writable Characteristics.  So we will rely purely on the connection being dropped before anything else can be written.  Or am I missing something?

  • My idea is to implement a mechanism so that right after you connect the app to the device (you can do bonding or not doesn't really mater), your app need to read the characteristic to get the random value (nounce ) . From that random value, the app need to use the secret key to generate a hash value and send back to the device using a write. If within 10 seconds (or less) , the app failed to do that or the hash value is not correct, the device will drop the connection. Within that 10 seconds, the device won't operate. 

    This process will be transparent to the end customer. If you reduce the timeout (instead of 10 seconds) it won't be noticed by the end customer. 

  • Understood.

    I will implement this, and let you know and verify your answer too.

    Thanks Hung Bui

  • Sure no problem. If you need a bit more secure, you can thinking of a public-private key pair. This way you can keep the private key only on the phone or on the cloud and leaving only the public key on the device, making it a little bit safer. 

  • Hi Hung Bui,

    I used a timeout handler to check a flag set by my password checking routine.  If the flag is not set i use this...

    ret_code_t err_code;

    err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    APP_ERROR_CHECK(err_code);

    Which then closes the connection.

    This is so simple and does exactly what we need,

    Thanks

Related