NRF51822蓝牙服务(7)——静态密码配对

2023-10-28 15:58

本文主要是介绍NRF51822蓝牙服务(7)——静态密码配对,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

有时候我们希望能够在连接的时候进行密钥的验证,以保障连接的安全。为了保证低功耗蓝牙的绝大多数安全特征,必须完成两个事情。首先是设备必须互相配对;其次,设备必须分配用于加密、保障隐私并对消息进行验证的密钥。这里我们尝试使用静态密码的方式完成蓝牙配对。

实验分析

这里,我们仍然使用前面的串口实验例程。

配对连接过程:

  1. 手机连接上之后立刻调用安全请求API(sd_ble_gap_authenticate),这样手机收到后就会发送配对请求。
  2. 回复手机的配对请求,设置不绑定。这样手机每次收到设备的安全请求就会发送配对请求过去从而启动配对。
  3. 之后的配对过程会自动进行。我们只需要根据收到的BLE_GAP_EVT_AUTH_STATUS事件,判断其状态是否成功,来决定配对是不是成功了,从而决定断不断开连接。

首先,我们先定义静态密码。

#define STATIC_PASSKEY "654321"

注意:官方规定配对密码只能是6位ASCII字符串

#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY     0x01   /**< 6-digit Passkey. *//**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */
typedef struct
{uint8_t passkey[BLE_GAP_PASSKEY_LEN];         /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
} ble_gap_evt_passkey_display_t;

接着定义密码操作结构体。

static ble_opt_t m_static_pin_option;

完成以上操作之后,我们需要设置一下静态密码,设置的操作需要在协议栈初始化之后,所以我们将设置密码操作放在gap_params_init()函数的最后:

{uint32_t                err_code;ble_gap_conn_params_t   gap_conn_params;ble_gap_conn_sec_mode_t sec_mode;BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);err_code = sd_ble_gap_device_name_set(&sec_mode,(const uint8_t *) DEVICE_NAME,strlen(DEVICE_NAME));APP_ERROR_CHECK(err_code);memset(&gap_conn_params, 0, sizeof(gap_conn_params));gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;gap_conn_params.slave_latency     = SLAVE_LATENCY;gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;err_code = sd_ble_gap_ppcp_set(&gap_conn_params);APP_ERROR_CHECK(err_code);uint8_t passkey[] = STATIC_PASSKEY; m_static_pin_option.gap_opt.passkey.p_passkey = passkey;err_code=sd_ble_opt_set(BLE_GAP_OPT_PASSKEY,&m_static_pin_option);APP_ERROR_CHECK(err_code);
}

然后是设置配对时要交换的信息:

下面定义我们需要交换的信息的宏,也就是和安全参数相关的一些宏。

//不需要绑定
#define SEC_PARAM_BOND     0
//因为要输入密码,就是一种MITM攻击保护,所以这里设置MITM
#define SEC_PARAM_MITM     1

完成这些之后。手机将会发来配对请求,之后设备需要回复,因此需要是实现配对回复函数:

#define SEC_PARAM_MIN_KEY_SIZE 7
#define SEC_PARAM_MAX_KEY_SIZE 16
ble_gap_sec_params_t sec_params;static void resp_pair_request()
{uint32_t err_code;	sec_params.bond = SEC_PARAM_BOND;sec_params.mitm = SEC_PARAM_MITM;sec_params.io_caps = SEC_PARAM_IO_CAPABILITIES;sec_params.oob = SEC_PARAM_OOB;sec_params.min_key_size = SEC_PARAM_MIN_KEY_SIZE;sec_params.max_key_size = SEC_PARAM_MAX_KEY_SIZE;err_code= sd_ble_gap_sec_params_reply(m_conn_handle,BLE_GAP_SEC_STATUS_SUCCESS,&sec_params,NULL);APP_ERROR_CHECK(err_code);
}

最后,就是添加上面说的第三个步骤的代码。

static void on_ble_evt(ble_evt_t * p_ble_evt)
{uint32_t                         err_code;switch (p_ble_evt->header.evt_id){case BLE_GAP_EVT_CONNECTED:err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);APP_ERROR_CHECK(err_code);m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;//一建立连接就发送安全请求,从而促使手机发送配对请求过来ble_gap_sec_params_t params;params.bond = SEC_PARAM_BOND;params.mitm = SEC_PARAM_MITM;sd_ble_gap_authenticate(m_conn_handle, &params);//break;case BLE_GAP_EVT_DISCONNECTED:err_code = bsp_indication_set(BSP_INDICATE_IDLE);APP_ERROR_CHECK(err_code);m_conn_handle = BLE_CONN_HANDLE_INVALID;break;case BLE_GAP_EVT_SEC_PARAMS_REQUEST:resp_pair_request();break;case BLE_GAP_EVT_PASSKEY_DISPLAY:break;//判断配对是否成功,如果不成功就断开连接,从而阻止他人任意连接case BLE_GAP_EVT_AUTH_STATUS:if(p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS){printf("Success!");}else{sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);}break;//case BLE_GATTS_EVT_SYS_ATTR_MISSING:// No system attributes have been stored.err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);APP_ERROR_CHECK(err_code);break;default:// No implementation needed.break;}
}

到这里,就完成了所有操作。

最后梳理下流程:手机连接设备后,设备会立即发送安全请求。因为手机和设备没有绑定,所以手机收到设备发送过来的安全请求后就会发送配对请求给设备。设备从而回复配对请求且不绑定,设备后续的配对过程由协议栈自动完成,并最终返回给上层配对完成事件。判断配对是否成功,如果失败就断开连接,从而阻止他人随意连接设备。

结果验证

  • 手机连接蓝牙,我们可以发现弹出密码输入窗口
  • 输入“654321”才能完成蓝牙配对
  • 断开蓝牙重连,发现仍然需要重新输入密码

总结

通过这个实验,我们学会了如何使用静态密码连接蓝牙。

这篇关于NRF51822蓝牙服务(7)——静态密码配对的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/294311

相关文章

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

TP-Link PDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务

《TP-LinkPDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务》近期,路由器制造巨头普联(TP-Link)在用户群体中引发了一系列重要变动,上个月,公司发出了一则通知,明确要求所... 路由器厂商普联(TP-Link)上个月发布公告要求所有用户必须完成实名认证后才能继续使用普联提供的 D

MySQL修改密码的四种实现方式

《MySQL修改密码的四种实现方式》文章主要介绍了如何使用命令行工具修改MySQL密码,包括使用`setpassword`命令和`mysqladmin`命令,此外,还详细描述了忘记密码时的处理方法,包... 目录mysql修改密码四种方式一、set password命令二、使用mysqladmin三、修改u

微服务架构之使用RabbitMQ进行异步处理方式

《微服务架构之使用RabbitMQ进行异步处理方式》本文介绍了RabbitMQ的基本概念、异步调用处理逻辑、RabbitMQ的基本使用方法以及在SpringBoot项目中使用RabbitMQ解决高并发... 目录一.什么是RabbitMQ?二.异步调用处理逻辑:三.RabbitMQ的基本使用1.安装2.架构

电脑密码怎么设置? 一文读懂电脑密码的详细指南

《电脑密码怎么设置?一文读懂电脑密码的详细指南》为了保护个人隐私和数据安全,设置电脑密码显得尤为重要,那么,如何在电脑上设置密码呢?详细请看下文介绍... 设置电脑密码是保护个人隐私、数据安全以及系统安全的重要措施,下面以Windows 11系统为例,跟大家分享一下设置电脑密码的具体办php法。Windo

解读静态资源访问static-locations和static-path-pattern

《解读静态资源访问static-locations和static-path-pattern》本文主要介绍了SpringBoot中静态资源的配置和访问方式,包括静态资源的默认前缀、默认地址、目录结构、访... 目录静态资源访问static-locations和static-path-pattern静态资源配置

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas