This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nRF51822 Peripheral with Passkey

Hi, like many others, I'm confused with Peripheral Passkey Connection.

I'm playing with the ble_app_hrs, in order to be able to setup a Connection Passkey (for the moment I would like to have a static hard-coded passkey). The goal of my application is to connect to the nRF51822 Peripheral using a Smartphone/Tablet and to be prompted to input a Passkey.

On main.c I set up these sec parameters:


#define SEC_PARAM_TIMEOUT                    30    
#define SEC_PARAM_BOND                       1
#define SEC_PARAM_MITM                       0
#define SEC_PARAM_IO_CAPABILITIES            BLE_GAP_IO_CAPS_KEYBOARD_ONLY
#define SEC_PARAM_OOB                        0
#define SEC_PARAM_MIN_KEY_SIZE               7
#define SEC_PARAM_MAX_KEY_SIZE               16

Then in the function on_ble_evt(ble_evt_t * p_ble_evt) in the case BLE_GAP_EVT_CONNECTED I've added err_code = sd_ble_gap_authenticate(m_conn_handle, &m_sec_params); to let the Peripheral initiate the security establishment (is this correct?).

The call of this function generates the event: BLE_GAP_EVT_SEC_INFO_REQUEST which I think I should reply with sd_ble_gap_sec_info_reply, is it correct?

I can't understand how to fill the parameters for the sd_ble_gap_sec_info_reply

Are those sec parameters correct for this application purposes?

Thanks for any help/suggestions.

Regards, Samuele.

  • In general, using a static passkey isn't really possible with BLE. It has previously been discussed for example here, here and here, and I'd recommend you to read all of those, as they all include information that may be useful to find a good security scheme for your application.

    Calling sd_ble_gap_sec_info_reply() is most often handled by the bond manager. For an example of how to use the bond manager, you can refer to this branch of the nrf51-ble-app-lbs example application.

    For completeness, if you want to implement this yourself instead, you are supposed to reply to this event with the keys for the connected device. You should be able to find the connected device in your database of bonded devices by using the information in the sec_info_request event, and you should pass the LTK that should be used back to the softdevice in the _reply() call. You can refer to this MSC, as well as the bond manager code for details. Beware that implementing a bond manager is not trivial, and will require a good understanding of the relevant parts of the Core Specification, in particular Volume 3, Part H.

    Finally, using _authenticate() is not recommended, especially not when working with iOS devices, as explained in Apple's Bluetooth Accessory Design Guidelines. Instead, you should make sure to set the permissions as you want on your characteristics (see the usage of BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM() above), so that an error will be returned to the Central when it tries to do something that requires encryption. This error will then trigger most Central devices to automatically start bonding.

  • Hi, thanks for your answer.

    So, setting a static passkey to pair with a Peripheral Device seems to be unfeasible... unless you write your own application-auth layer on top of BLE.

    I was thinking about the passkey pairing because I have a BLE Peripheral Device that needs to work in 2 modes: CONF_MODE and WORK_MODE, in CONF_MODE the device should expose some configuration services/characteristics that only a Device Manager (the man who know the password) should be able to edit, while in WORK_MODE the device exposes others services/characteristics, those needed for its ordinary work. The two operating modes are switched by pressing a button on the board.

    Do you have any experience/suggestions/solutions on how to implement a BLE Peripheral Device that should be capable to authenticate only the users that have the right "password"?

    Thanks again for your answer. Regards, Samuele.

  • I don't have any readymade suggestions for anything like this, but it's certain that implementing this on the application level is better than trying to use a static Bluetooth passkey for bonding. Since passkeys are only 6 digits, it would be trivial for someone to brute-force this if wanted.

    One possibility could for example be to have the two devices share a key beforehand (i.e. as part of the firmware image and of the app), and then doing encryption of a dynamically shared value, comparing the results and then only let the device access the configuration mode if the values matches. If security is of great concern, I would however recommend you to talk to some security expert before moving ahead, as there could very well be flaws in such scheme, that I've overlooked.

    Also, I think you're better off by just always having the services there, but just disallowing operations before authentication has been passed. This saves you the trouble of sending Service Changed indications and similar, when the service setup changes.

    Finally, since I believe my first reply answered your original question, I'd be happy if you could accept it, to clear up this question. :)

  • Hi Samuele,

    I have the same problem with you and I want to know wheather your problem solved.

    Could you share the solutions with me ,thank you so much!

  • Hi, as Ole Morten said, there isn't a Bluetooth LE standard way to obtain a static authentication with such devices. We have implemented the authentication procedure at application level using a custom GATT Service/Characteristics and checking for a password (that can be static or changeable) to authenticate the connected device. I haven't found any other solution yet...

Related