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

相关文章

如何搭建并配置HTTPD文件服务及访问权限控制

《如何搭建并配置HTTPD文件服务及访问权限控制》:本文主要介绍如何搭建并配置HTTPD文件服务及访问权限控制的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、安装HTTPD服务二、HTTPD服务目录结构三、配置修改四、服务启动五、基于用户访问权限控制六、

Druid连接池实现自定义数据库密码加解密功能

《Druid连接池实现自定义数据库密码加解密功能》在现代应用开发中,数据安全是至关重要的,本文将介绍如何在​​Druid​​连接池中实现自定义的数据库密码加解密功能,有需要的小伙伴可以参考一下... 目录1. 环境准备2. 密码加密算法的选择3. 自定义 ​​DruidDataSource​​ 的密码解密3

电脑蓝牙连不上怎么办? 5 招教你轻松修复Mac蓝牙连接问题的技巧

《电脑蓝牙连不上怎么办?5招教你轻松修复Mac蓝牙连接问题的技巧》蓝牙连接问题是一些Mac用户经常遇到的常见问题之一,在本文章中,我们将提供一些有用的提示和技巧,帮助您解决可能出现的蓝牙连接问... 蓝牙作为一种流行的无线技术,已经成为我们连接各种设备的重要工具。在 MAC 上,你可以根据自己的需求,轻松地

SpringBoot如何对密码等敏感信息进行脱敏处理

《SpringBoot如何对密码等敏感信息进行脱敏处理》这篇文章主要为大家详细介绍了SpringBoot对密码等敏感信息进行脱敏处理的几个常用方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录​1. 配置文件敏感信息脱敏​​2. 日志脱敏​​3. API响应脱敏​​4. 其他注意事项​​总结

JavaScript实战:智能密码生成器开发指南

本文通过JavaScript实战开发智能密码生成器,详解如何运用crypto.getRandomValues实现加密级随机密码生成,包含多字符组合、安全强度可视化、易混淆字符排除等企业级功能。学习密码强度检测算法与信息熵计算原理,获取可直接嵌入项目的完整代码,提升Web应用的安全开发能力 目录

SpringCloud整合MQ实现消息总线服务方式

《SpringCloud整合MQ实现消息总线服务方式》:本文主要介绍SpringCloud整合MQ实现消息总线服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、背景介绍二、方案实践三、升级版总结一、背景介绍每当修改配置文件内容,如果需要客户端也同步更新,

使用Java实现Navicat密码的加密与解密的代码解析

《使用Java实现Navicat密码的加密与解密的代码解析》:本文主要介绍使用Java实现Navicat密码的加密与解密,通过本文,我们了解了如何利用Java语言实现对Navicat保存的数据库密... 目录一、背景介绍二、环境准备三、代码解析四、核心代码展示五、总结在日常开发过程中,我们有时需要处理各种软

linux服务之NIS账户管理服务方式

《linux服务之NIS账户管理服务方式》:本文主要介绍linux服务之NIS账户管理服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、所需要的软件二、服务器配置1、安装 NIS 服务2、设定 NIS 的域名 (NIS domain name)3、修改主

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾