首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【0x0011】HCI_Authentication_Requested命令详解

【0x0011】HCI_Authentication_Requested命令详解

作者头像
byte轻骑兵
发布2026-01-21 14:23:48
发布2026-01-21 14:23:48
660
举报

HCI_Authentication_Requested命令主要用于在蓝牙设备之间建立安全连接时,请求对远端设备进行认证。这是蓝牙安全机制的一部分,确保只有经过认证的设备才能建立连接并交换数据。

一、命令概述

在蓝牙通信中,安全性是一个非常重要的考虑因素。通过认证过程,可以验证设备的身份,防止未经授权的设备接入网络,从而保护数据的机密性和完整性。

当主机(Host)决定与某个远端蓝牙设备进行通信时,可能会发送HCI_Authentication_Requested命令给蓝牙控制器(Controller)。这个命令包含了要认证的连接的连接句柄(Connection_Handle),用于指定哪个连接需要进行认证。

一旦接收到这个命令,蓝牙控制器会尝试与远端设备进行认证。涉及到一系列复杂的交互,包括交换认证信息、验证身份等。如果认证成功,控制器会向主机发送一个认证完成事件(Authentication Complete Event),表明远端设备已经成功通过认证,可以建立安全连接。

如果认证失败,控制器通常不会自动断开连接。这时,主机需要决定是否继续尝试认证,或者断开与远端设备的连接。

二、命令格式及参数说明

2.1. HCI_Authentication_Requested命令格式

HCI_Authentication_Requested命令的格式遵循蓝牙核心规范中定义的HCI命令格式。

通常包括以下几个部分:

  • Opcode(操作码):2字节。指示命令的类型。对于HCI_Authentication_Requested命令,操作码为0x0411
  • Parameter_Total_Length(参数总长度):1字节。表示命令参数的总长度。对于HCI_Authentication_Requested命令,参数总长度为0x02(即2个字节)。
  • Parameters(参数):可变长度(根据Parameter_Total_Length确定),对于HCI_Authentication_Requested命令,只有一个参数:
    • Connection_Handle(连接句柄):2字节。指定要认证的蓝牙连接

2.2. Connection_Handle

Connection_Handle用于唯一标识ACL连接或某些情况下的SCO连接的句柄。该句柄是在连接建立时由蓝牙控制器分配的,并用于后续的HCI命令和数据包中,以指定要操作的具体连接。

  • 有效性:虽然Connection_Handle是一个16位的值,但根据蓝牙核心规范,通常只有其中的12位是有效的。意味着在实际使用中,某些高位不被使用。
  • 范围限制Connection_Handle的值必须在0x00000x0EFF的范围内。如果尝试使用超出此范围的值,蓝牙控制器可能会返回一个错误状态。

三、生成事件及参数说明

HCI_Authentication_Requested 命令本身没有直接返回的参数。主机在发送该命令后,不会立刻接收到像传统函数调用那样带有明确返回值的数据来知晓命令执行情况,而是需要通过后续控制器发送的各类事件来获取相关信息,以此判断命令执行的进度和最终结果。

3.1. HCI_Command_Status事件

当控制器(Controller)接收到 HCI_Authentication_Requested 命令时,首先会向主机发送 HCI_Command_Status 事件。这个事件主要起到告知主机命令已被接收的作用,主机可以通过解析该事件来确认命令是否成功送达控制器,不过此时还不能得知命令是否真正执行成功以及后续认证流程的具体情况,只是一个初步的反馈。

3.2. 安全简单配对模式(Secure Simple Pairing Mode)启用时的事件生成

3.2.1. HCI_Link_Key_Request事件

如果安全简单配对模式被启用,控制器会生成HCI_Link_Key_Request事件。这个事件表示与特定蓝牙设备的连接需要一个链接密钥(Link Key)。

3.2.2. 主机回复与事件后续

此时,后续的操作取决于主机回复的命令:

3.3. 安全简单配对模式未启用时的事件生成

如果安全简单配对模式未启用,控制器可能会(但不应该)使用已存储的链接密钥进行认证。如果认证失败,可能会生成HCI_PIN_Code_Request事件,要求输入PIN码进行认证。

然而,当安全简单配对模式未启用时,使用已存储的链接密钥是不被推荐的,因为这不能为主机提供一种增强现有链路安全性的方法。例如,当在某个已经通过较短PIN码认证的链路上启动需要更长PIN码的服务时,这种方法就无法提供足够的安全性。

3.4. HCI_Authentication_Complete事件

无论是否启用了安全简单配对模式,当连接的认证完成时,都会生成HCI_Authentication_Complete事件。这个事件表示HCI_Authentication_Requested命令已完成,并且连接的认证过程已经结束。

主机可以通过解析该事件获取认证的最终结果(成功或失败),进而根据自己的安全策略和业务需求来决定后续对该连接的操作,比如继续保持连接、断开连接或者尝试重新认证等。

蓝牙HCI认证过程中涉及的事件生成与是否启用安全简单配对模式以及主机的回复密切相关。这些事件为蓝牙设备的认证和连接管理提供了重要的反馈和指示。

四、命令执行流程

4.1. 发送认证请求

主机(Host)向控制器(Controller)发送HCI_Authentication_Requested命令,请求对远端设备进行认证。该命令中包含一个Connection_Handle参数,用于表示本地设备和远端设备之间的ACL连接。

4.2. 接收命令状态事件

控制器在接收到HCI_Authentication_Requested命令后,会立即向主机发送一个Command Status事件,表示该命令是否成功发送。

4.3. 处理Link Key请求事件

如果Simple Pairing模式已启用,控制器会向主机发送一个Link Key Request事件,请求一个Link Key。Link Key是用于加密和认证蓝牙设备之间连接的密钥。

  • 主机在接收到Link Key Request事件后,有以下两种选择:
    • 如果主机有对应的Link Key,则使用HCI_Link_Key_Request_Reply命令将Link Key发送给控制器。
    • 如果主机没有对应的Link Key,则使用HCI_Link_Key_Request_Negative_Reply命令进行回复,表示无法提供Link Key。
  • 如果Simple Pairing模式未启用,控制器同样会发送Link Key Request事件。此时,主机的处理方式与上述相同。但如果主机回复了HCI_Link_Key_Request_Negative_Reply命令,并且即将用到的服务需要一个认证的Link Key,那么在之后的IO Capability中,主机应设置Authentication_Requirements为MITM Protection Required的选项。

4.4. 处理PIN码请求事件(如适用)

  • 如果主机在Link Key请求阶段回复了HCI_Link_Key_Request_Negative_Reply命令,并且Simple Pairing模式已启用,那么控制器可能会向主机发送一个PIN Code Request事件,请求一个PIN码进行认证。
  • 主机在接收到PIN Code Request事件后,需要回复PIN码。如果PIN码认证成功,控制器会生成并发送一个Link Key Notification事件给主机,表示Link Key已生成并可用于后续的连接加密和认证。

4.5. 接收认证完成事件

如果认证过程成功完成,控制器会向主机发送一个Authentication Complete事件,表示认证已成功完成。

4.6. 后续操作

  • 如果身份验证成功,主机可以继续进行后续操作,如数据传输等。
  • 如果身份验证失败,主机需要决定是否断开链路。如果需要断开,主机应发送 HCI_Disconnect 命令。

需要注意的是,在整个认证过程中,如果任何一步出现错误或超时,都可能导致认证失败。此时,主机可能需要重新发起认证请求或采取其他措施来处理认证失败的情况。

此外,HCI_Authentication_Requested命令的执行流程还可能受到蓝牙设备型号、固件版本、配对策略等因素的影响。因此,在实际应用中,可能需要根据具体的设备和环境对流程进行适当的调整和优化。

4.7. 示例代码

下面是一个简化的伪代码示例,来概述主机和控制器之间如何交互以执行HCI_Authentication_Requested命令。请注意,这只是一个概念性的示例,并不是可编译的代码。

代码语言:javascript
复制
// 伪代码示例:HCI_Authentication_Requested流程
 
// 假设有以下函数和变量定义(这些在实际代码中需要由蓝牙协议栈提供):
 
// 发送HCI命令给控制器的函数
void hci_send_command(uint16_t opcode, uint8_t* parameters, uint8_t parameter_length);
 
// 接收HCI事件的回调函数(由蓝牙协议栈在接收到事件时调用)
void hci_event_callback(uint8_t* event, uint8_t event_length);
 
// 全局变量,用于存储连接句柄
uint16_t connection_handle = 0x0001; // 示例连接句柄
 
// 认证过程中的状态变量
enum AuthenticationState {
    WAITING_FOR_COMMAND_STATUS,
    WAITING_FOR_LINK_KEY_REQUEST,
    WAITING_FOR_PIN_CODE_REQUEST,
    WAITING_FOR_AUTHENTICATION_COMPLETE,
    AUTHENTICATION_FAILED
} authentication_state = WAITING_FOR_COMMAND_STATUS;
 
// 用于存储Link Key和PIN码的变量(在实际代码中,这些可能需要更安全的存储方式)
uint8_t link_key[16] = {0}; // 示例Link Key(16字节)
uint8_t pin_code[16] = "0000"; // 示例PIN码(4字节,ASCII表示)
 
// 发送HCI_Authentication_Requested命令的函数
void send_authentication_request() {
    uint8_t parameters[2] = {
        connection_handle & 0xFF, // 连接句柄的低字节
        (connection_handle >> 8) & 0xFF // 连接句柄的高字节
    };
    hci_send_command(0x0011, parameters, sizeof(parameters)); // 0x0011是HCI_Authentication_Requested的操作码
}
 
// HCI事件回调函数的实现
void hci_event_callback(uint8_t* event, uint8_t event_length) {
    uint8_t event_code = event[0];
    uint8_t status = event[1];
 
    switch (event_code) {
        case 0x0F: // Command Status event
            if (status == 0x00) {
                authentication_state = WAITING_FOR_LINK_KEY_REQUEST;
            } else {
                authentication_state = AUTHENTICATION_FAILED;
                // 处理命令发送失败的情况
            }
            break;
 
        case 0x05: // Link Key Request event
            if (authentication_state == WAITING_FOR_LINK_KEY_REQUEST) {
                // 检查是否有可用的Link Key
                if (has_link_key()) { // 这是一个假设的函数,用于检查Link Key是否存在
                    // 发送Link Key给控制器(这里省略了构建和发送HCI_Link_Key_Request_Reply命令的细节)
                    send_link_key_reply(link_key);
                } else {
                    // 发送Link Key Request Negative Reply给控制器(同样省略了细节)
                    send_link_key_negative_reply();
                    authentication_state = WAITING_FOR_PIN_CODE_REQUEST; // 假设需要PIN码
                }
            }
            break;
 
        case 0x06: // Link Key Notification event(在PIN码认证成功后由控制器发送)
            // 更新内部状态或执行其他操作(如记录新的Link Key)
            break;
 
        case 0x0E: // PIN Code Request event
            if (authentication_state == WAITING_FOR_PIN_CODE_REQUEST) {
                // 发送PIN码给控制器(这里省略了构建和发送PIN码的细节)
                send_pin_code_reply(pin_code);
            }
            break;
 
        case 0x0B: // Authentication Complete event
            if (status == 0x00) {
                // 认证成功,执行后续操作(如加密连接)
                authentication_state = -1; // 设置为无效状态,表示认证流程已完成
            } else {
                authentication_state = AUTHENTICATION_FAILED;
                // 处理认证失败的情况
            }
            break;
 
        // 其他事件的处理...
 
        default:
            // 未知事件的处理
            break;
    }
}
 
// 省略了其他必要的函数实现,如send_link_key_reply(), send_link_key_negative_reply(), send_pin_code_reply()等。
// 这些函数需要构建适当的HCI命令数据包,并通过HCI接口发送给蓝牙控制器。
 
// 主函数(或某个初始化函数中)调用发送认证请求的函数
int main() {
    // 初始化蓝牙协议栈和其他必要的设置...
 
    // 发送认证请求
    send_authentication_request();
 
    // 进入事件循环,等待并处理HCI事件...
    // 这通常是通过注册一个回调函数给蓝牙协议栈来实现的,当有事件发生时,蓝牙协议栈会调用这个回调函数。
 
    return 0;
}

上面的代码是一个高度简化的示例,省略了许多细节,在实际开发中,需要参考蓝牙协议栈的文档和API来编写完整的代码。

五、使用场景

5.1. 设备配对与安全验证

  • 初次配对后的加强验证
    • 场景:蓝牙耳机与手机初次配对成功后。
    • 目的:通过发送HCI_Authentication_Requested命令,使用配对时生成的密钥(如链路密钥)对从设备进行额外认证,防止中间人攻击,确保数据传输安全。
  • 配对信息更新后的验证
    • 场景:设备配对信息(密钥、设备标识等)发生更新。
    • 目的:使用HCI_Authentication_Requested命令重新验证连接的设备,确保使用最新的安全信息进行通信,保障数据安全。

5.2. 高安全需求服务访问

  • 金融服务相关蓝牙设备连接
    • 场景:蓝牙移动支付终端与手机、蓝牙智能卡读卡器与电脑等金融相关设备连接。
    • 目的:在认证成功后,才允许访问和传输金融服务相关的数据,防止未经授权的设备获取金融信息,确保交易安全。
  • 企业级安全蓝牙设备通信
    • 场景:蓝牙门禁系统、蓝牙企业级传感器等设备与控制中心或管理设备连接。
    • 目的:确保只有经过授权的设备能够接入企业内部的蓝牙网络,访问企业敏感数据或执行关键操作,符合企业安全策略。

5.3. 蓝牙设备连接状态变更

  • 连接恢复后的安全确认
    • 场景:蓝牙设备之间的连接因信号中断、低功耗模式等原因中断后恢复。
    • 目的:通过发送HCI_Authentication_Requested命令,确保重新连接的设备仍然是合法的,继续安全地处理数据。
  • 连接模式切换后的认证
    • 场景:蓝牙设备之间的连接模式从低功耗模式切换到高速数据传输模式,或从仅广播模式切换到可连接模式。
    • 目的:确保在连接模式变化后,设备之间的通信仍然是安全可靠的,防止非法设备利用连接模式切换进行攻击。

六、注意事项

6.1. 参数准确性与合法性

  • 连接句柄的准确性
    • 确保连接句柄对应有效的、活动的ACL连接。
    • 主机设备需维护连接句柄的存储和更新机制。
  • 参数取值范围遵守
    • 连接句柄应在蓝牙协议规定的合法取值范围内。
    • 注意连接句柄的有效位数量。

6.2. 设备兼容性与安全策略适配

  • 不同蓝牙版本兼容性
    • 考虑设备间蓝牙版本的兼容性,选择合适的认证方式。
    • 根据双方支持的最低共同标准执行命令。
  • 安全策略一致性
    • 确保设备双方的安全策略一致或兼容。
    • 在设备配对或配置过程中明确安全策略,必要时进行协商或调整。

6.3. 认证结果处理与连接维护

  • 正确处理认证成功情况
    • 更新内部安全状态记录,标记连接为已认证。
    • 允许受保护的蓝牙服务访问或数据传输。
  • 妥善应对认证失败情况
    • 解析并记录认证失败原因。
    • 根据失败原因和策略决定是否重新尝试认证、提示用户或断开连接。
  • 连接状态的维护与更新
    • 在认证过程中维护连接状态信息。
    • 根据认证结果和业务需求恢复或调整连接状态。

6.4. 安全风险与隐私保护

  • 防止中间人攻击风险
    • 采用足够强度的安全协议和加密算法。
    • 确保密钥的安全性和保密性。
  • 隐私保护措施
    • 使用匿名设备标识或临时密钥进行认证。
    • 注意认证过程中数据传输的安全性。

6.5. 其他注意事项

  • 认证过程的响应:根据Simple Pairing模式的状态,准备并回复相应的Link Key或PIN码请求。
  • 认证失败的处理:主机需主动断开连接,或在必要时重新尝试认证或重新配对。
  • 安全考虑:在认证过程中使用安全的通信方式。支持Secure Connections特性的设备应在断开连接后删除Link Key。
  • 命令格式和参数:按照HCI协议规范构造命令格式和参数。注意参数总长度和连接句柄的正确性。
  • 超时和重试机制:设置合理的超时时间,并在超时后考虑重试认证请求。设计重试机制以应对可能的认证失败情况。

综上所述,HCI_Authentication_Requested 命令是蓝牙 BR/EDR 控制器中用于发起远程设备身份验证的关键命令。通过正确使用该命令,可以确保蓝牙连接的安全性,并允许主机在身份验证失败时采取适当的行动。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、命令概述
  • 二、命令格式及参数说明
    • 2.1. HCI_Authentication_Requested命令格式
    • 2.2. Connection_Handle
  • 三、生成事件及参数说明
    • 3.1. HCI_Command_Status事件
    • 3.2. 安全简单配对模式(Secure Simple Pairing Mode)启用时的事件生成
      • 3.2.1. HCI_Link_Key_Request事件
      • 3.2.2. 主机回复与事件后续
    • 3.3. 安全简单配对模式未启用时的事件生成
    • 3.4. HCI_Authentication_Complete事件
  • 四、命令执行流程
    • 4.1. 发送认证请求
    • 4.2. 接收命令状态事件
    • 4.3. 处理Link Key请求事件
    • 4.4. 处理PIN码请求事件(如适用)
    • 4.5. 接收认证完成事件
    • 4.6. 后续操作
    • 4.7. 示例代码
  • 五、使用场景
    • 5.1. 设备配对与安全验证
    • 5.2. 高安全需求服务访问
    • 5.3. 蓝牙设备连接状态变更
  • 六、注意事项
    • 6.1. 参数准确性与合法性
    • 6.2. 设备兼容性与安全策略适配
    • 6.3. 认证结果处理与连接维护
    • 6.4. 安全风险与隐私保护
    • 6.5. 其他注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档