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

相关文章

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

Spring LDAP目录服务的使用示例

《SpringLDAP目录服务的使用示例》本文主要介绍了SpringLDAP目录服务的使用示例... 目录引言一、Spring LDAP基础二、LdapTemplate详解三、LDAP对象映射四、基本LDAP操作4.1 查询操作4.2 添加操作4.3 修改操作4.4 删除操作五、认证与授权六、高级特性与最佳

Python从零打造高安全密码管理器

《Python从零打造高安全密码管理器》在数字化时代,每人平均需要管理近百个账号密码,本文将带大家深入剖析一个基于Python的高安全性密码管理器实现方案,感兴趣的小伙伴可以参考一下... 目录一、前言:为什么我们需要专属密码管理器二、系统架构设计2.1 安全加密体系2.2 密码强度策略三、核心功能实现详解

Linux上设置Ollama服务配置(常用环境变量)

《Linux上设置Ollama服务配置(常用环境变量)》本文主要介绍了Linux上设置Ollama服务配置(常用环境变量),Ollama提供了多种环境变量供配置,如调试模式、模型目录等,下面就来介绍一... 目录在 linux 上设置环境变量配置 OllamPOgxSRJfa手动安装安装特定版本查看日志在

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

Linux系统中配置静态IP地址的详细步骤

《Linux系统中配置静态IP地址的详细步骤》本文详细介绍了在Linux系统中配置静态IP地址的五个步骤,包括打开终端、编辑网络配置文件、配置IP地址、保存并重启网络服务,这对于系统管理员和新手都极具... 目录步骤一:打开终端步骤二:编辑网络配置文件步骤三:配置静态IP地址步骤四:保存并关闭文件步骤五:重

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

MyBatis-Plus中静态工具Db的多种用法及实例分析

《MyBatis-Plus中静态工具Db的多种用法及实例分析》本文将详细讲解MyBatis-Plus中静态工具Db的各种用法,并结合具体案例进行演示和说明,具有很好的参考价值,希望对大家有所帮助,如有... 目录MyBATis-Plus中静态工具Db的多种用法及实例案例背景使用静态工具Db进行数据库操作插入

Nginx配置系统服务&设置环境变量方式

《Nginx配置系统服务&设置环境变量方式》本文介绍了如何将Nginx配置为系统服务并设置环境变量,以便更方便地对Nginx进行操作,通过配置系统服务,可以使用系统命令来启动、停止或重新加载Nginx... 目录1.Nginx操作问题2.配置系统服android务3.设置环境变量总结1.Nginx操作问题

Oracle登录时忘记用户名或密码该如何解决

《Oracle登录时忘记用户名或密码该如何解决》:本文主要介绍如何在Oracle12c中忘记用户名和密码时找回或重置用户账户信息,文中通过代码介绍的非常详细,对同样遇到这个问题的同学具有一定的参... 目录一、忘记账户:二、忘记密码:三、详细情况情况 1:1.1. 登录到数据库1.2. 查看当前用户信息1.