【BlueZ 】蓝牙配对/绑定基础:BlueZ 中安全机制的入门级源码解析

在蓝牙技术的应用场景中,从无线耳机传输音频、智能手表同步健康数据,到 IoT 设备控制家居,数据传输的安全性至关重要。蓝牙安全机制主要解决以下问题:

  • 身份验证:确保连接的是可信设备,防止中间人攻击

  • 数据加密:保护传输中的数据不被窃听

  • 访问控制:限制非授权设备的访问


目录

一、安全机制架构总览

二、配对流程核心解析

三、认证与密钥交互

四、密钥生成与存储

五、设备绑定完成处理

[六、经典蓝牙与 BLE 配对差异](#六、经典蓝牙与 BLE 配对差异)

七、常见问题与解决方案

八、核心函数索引

九、总结


在深入源码之前,必须明确两个核心概念的区别:

|-----------------|--------------|-----------|-----------|
| 概念 | 定义 | 过程 | 结果 |
| 配对(Pairing) | 设备间建立信任关系的过程 | 交换密钥、验证身份 | 生成短期/长期密钥 |
| 绑定(Bonding) | 将配对信息持久化存储 | 存储密钥到本地 | 下次连接自动认证 |

关键区别

  • 配对是一次性的认证过程

  • 绑定是将配对结果保存到持久化存储

  • 未绑定的设备断电后需要重新配对

蓝牙安全发展历程:

|---------------|-----------------------|------------|
| 版本 | 核心特性 | 安全等级 |
| Bluetooth 2.0 | PIN 码配对 | 较低(4-16 位) |
| Bluetooth 2.1 | SSP(安全简单配对) | 较高(128 位) |
| Bluetooth 4.0 | LE Secure Connections | BLE 专用 |
| Bluetooth 4.2 | LE Secure Connections | 支持 MITM 保护 |


一、安全机制架构总览

1.1 BlueZ 安全模块架构

BlueZ 的安全机制涉及多个核心模块:

1.2 核心数据结构

1.2.1 绑定请求结构

cpp 复制代码
// src/device.c - 绑定请求结构
struct bonding_req {
    DBusMessage *msg;              /* DBus 请求消息 */
    guint listener_id;             /* 监听器 ID */
    struct btd_device *device;     /* 目标设备 */
    uint8_t bdaddr_type;          /* 地址类型 */
    struct agent *agent;           /* 认证 Agent */
    struct btd_adapter_pin_cb_iter *cb_iter;  /* 回调迭代器 */
    uint8_t status;                /* 绑定状态 */
    guint retry_timer;            /* 重试定时器 */
    struct timespec attempt_start_time;  /* 开始时间 */
    long last_attempt_duration_ms; /* 上次尝试耗时 */
};

1.2.2 设备安全状态

cpp 复制代码
// src/device.c - 承载状态结构
struct bearer_state {
    bool connected;     /* 已连接 */
    bool paired;        /* 已配对 */
    bool bonded;        /* 已绑定 */
    bool connecting;    /* 连接中 */
    bool disconnecting; /* 断开中 */
    bool pairing;       /* 配对中 */
    bool svc_resolved;  /* 服务已解析 */
    bool autorized;     /* 已授权 */
};

// 设备结构中的安全状态
struct btd_device {
    // ...
    struct bearer_state bredr_state;  /* BR/EDR 安全状态 */
    struct bearer_state le_state;     /* BLE 安全状态 */
    struct bonding_req *bonding;      /* 当前绑定请求 */
    struct authentication_req *authr; /* 当前认证请求 */
    // ...
};

二、配对流程核心解析

2.1 配对触发入口

2.1.1 DBus 接口触发

cpp 复制代码
// src/device.c - Pair 方法处理
static DBusMessage *pair_device(DBusConnection *conn,
                                DBusMessage *msg, void *user_data)
{
    struct btd_device *device = user_data;
    struct btd_adapter *adapter = device_get_adapter(device);
    int err;
    
    // 检查设备状态
    if (device->bonding)
        return btd_error_already_exists(msg);
    
    // 启动配对流程
    err = btd_adapter_create_bonding(adapter, device, msg);
    if (err < 0)
        return btd_error_failed(msg, err);
    
    device->pairing = TRUE;
    
    return NULL;
}

2.1.2 适配器 绑定创建

cpp 复制代码
// src/adapter.c - 创建绑定请求
int adapter_create_bonding(struct btd_adapter *adapter, 
                          const bdaddr_t *bdaddr,
                          uint8_t addr_type, uint8_t io_cap)
{
    // 暂停发现流程
    suspend_discovery(adapter);
    
    // 开始绑定尝试
    return adapter_bonding_attempt(adapter, bdaddr, addr_type, io_cap);
}

2.2 配对命令下发

2.2.1 发送 Pair Device 命令

cpp 复制代码
// src/adapter.c - 发送配对命令
int adapter_bonding_attempt(struct btd_adapter *adapter, 
                           const bdaddr_t *bdaddr,
                           uint8_t addr_type, uint8_t io_cap)
{
    struct mgmt_cp_pair_device cp;
    struct pair_device_data *data;
    unsigned int id;
    
    // 准备命令参数
    memset(&cp, 0, sizeof(cp));
    bacpy(&cp.addr.bdaddr, bdaddr);
    cp.addr.type = addr_type;
    cp.io_cap = io_cap;  /* 输入输出能力 */
    
    // 创建回调数据
    data = g_new0(struct pair_device_data, 1);
    data->adapter = adapter;
    bacpy(&data->bdaddr, bdaddr);
    data->addr_type = addr_type;
    
    // 通过 Management Interface 发送命令
    id = mgmt_send_timeout(adapter->mgmt, MGMT_OP_PAIR_DEVICE,
                adapter->dev_id, sizeof(cp), &cp,
                pair_device_complete, data,
                free_pair_device_data, BONDING_TIMEOUT);
    if (id == 0) {
        btd_error(adapter->dev_id, "Failed to pair for hci%u",
                            addr, adapter->dev_id);
        free_pair_device_data(data);
        return -EIO;
    }
    
    return 0;
}

2.2.2 IO 能力参数说明

cpp 复制代码
// 输入输出能力 (IO Capability)
#define BT_IO_CAP_OUT    0x01  /* 仅输出 (如: 耳机) */
#define BT_IO_CAP_IN    0x02  /* 仅输入 (如: 键盘) */
#define BT_IO_CAP_IO    0x03  /* 输入输出 (如: 手机) */
#define BT_IO_CAP_NONE  0x04  /* 无 (如: 传感器) */

IO 能力决定配对方式

|-----------------|-----------------|----------|
| 本端能力 | 对端能力 | 配对方式 |
| DisplayYesNo | DisplayYesNo | 数字比较 |
| KeyboardDisplay | DisplayYesNo | 键盘输入 |
| NoInputNoOutput | NoInputNoOutput | 无安全 |
| KeyboardOnly | KeyboardOnly | 密码输入 |

2.3 配对响应处理

2.3.1 配对完成回调

cpp 复制代码
// src/adapter.c - 配对完成回调
static void pair_device_complete(uint8_t status, uint16_t length,
                    const void *param, void *user_data)
{
    const struct mgmt_rp_pair_device *rp = param;
    struct pair_device_data *data = user_data;
    struct btd_adapter *adapter = data->adapter;
    
    DBG("%s (0x%02x)", mgmt_errstr(status), status);
    
    // 处理内核 Bug:命令状态异常
    if (status != MGMT_STATUS_SUCCESS && length < sizeof(*rp)) {
        btd_error(adapter->dev_id, "Pair device failed: %s (0x%02x)",
                        mgmt_errstr(status), status);
        bonding_attempt_complete(adapter, &data->bdaddr,
                            data->addr_type, status);
        return;
    }
    
    // 正常完成
    bonding_attempt_complete(adapter, &rp->addr.bdaddr, 
                            rp->addr.type, status);
}

2.3.2 绑定尝试完成

cpp 复制代码
// src/adapter.c - 绑定尝试完成
static void bonding_attempt_complete(struct btd_adapter *adapter,
                    const bdaddr_t *bdaddr, uint8_t addr_type, 
                    uint8_t status)
{
    struct btd_device *device;
    
    // 状态为 0 表示成功
    if (status == 0)
        device = btd_adapter_get_device(adapter, bdaddr, addr_type);
    else
        device = btd_adapter_find_device(adapter, bdaddr, addr_type);
    
    // 检查是否需要重试
    if (status != 0 && device && device_is_retrying(device))
        return;
    
    // 完成绑定流程
    bonding_complete(adapter, bdaddr, addr_type, status);
}

2.3.3 绑定完成处理

cpp 复制代码
// src/adapter.c - 绑定完成
static void bonding_complete(struct btd_adapter *adapter,
                    const bdaddr_t *bdaddr, uint8_t addr_type, 
                    uint8_t status)
{
    struct btd_device *device;
    
    if (status == 0)
        device = btd_adapter_get_device(adapter, bdaddr, addr_type);
    else
        device = btd_adapter_find_device(adapter, bdaddr, addr_type);
    
    if (device != NULL)
        device_bonding_complete(device, addr_type, status);
    
    // 恢复发现流程
    resume_discovery(adapter);
    
    // 检查 OOB 绑定完成
    check_oob_bonding_complete(adapter, bdaddr, status);
}

三、认证与密钥交互

3.1 密码请求处理

3.1.1 PIN 码/密码请求

cpp 复制代码
// src/adapter.c - PIN 码请求事件处理
static void user_passkey_request_callback(uint16_t index, uint16_t length,
                    const void *param, void *user_data)
{
    const struct mgmt_ev_user_passkey_request *ev = param;
    struct btd_adapter *adapter = user_data;
    struct btd_device *device;
    int err;
    
    // 查找设备
    device = btd_adapter_get_device(adapter, &ev->addr.bdaddr, ev->addr.type);
    if (!device)
        return;
    
    // 请求用户输入密码
    err = device_request_passkey(device, ev->addr.type);
    if (err < 0) {
        btd_adapter_passkey_reply(adapter, &ev->addr.bdaddr,
                    ev->addr.type, INVALID_PASSKEY);
    }
}

3.1.2 数字比较确认

cpp 复制代码
// src/adapter.c - 数字比较事件处理
static void user_confirm_request_callback(uint16_t index, uint16_t length,
                    const void *param, void *user_data)
{
    const struct mgmt_ev_user_confirm_request *ev = param;
    struct btd_adapter *adapter = user_data;
    struct btd_device *device;
    int err;
    
    device = btd_adapter_get_device(adapter, &ev->addr.bdaddr, ev->addr.type);
    if (!device)
        return;
    
    // 请求用户确认(显示 6 位数字)
    err = device_confirm_passkey(device, ev->addr.type, 
                btohl(ev->value), ev->confirm_hint);
    if (err < 0) {
        btd_adapter_confirm_reply(adapter, &ev->addr.bdaddr,
                    ev->addr.type, FALSE);
    }
}

3.2 密钥通知处理

3.2.1 密码输入通知

cpp 复制代码
// src/adapter.c - 密码输入事件
static void user_passkey_notify_callback(uint16_t index, uint16_t length,
                    const void *param, void *user_data)
{
    const struct mgmt_ev_passkey_notify *ev = param;
    struct btd_adapter *adapter = user_data;
    uint32_t passkey;
    
    // 获取密码值
    passkey = btohl(ev->passkey);
    
    DBG("passkey %06u entered %u", passkey, ev->entered);
    
    // 通知用户密码(用于显示)
    if (!ev->entered)
        device_notify_passkey(device, adapter->bdaddr_type, 
                    passkey, FALSE);  /* 显示密码给用户 */
}

四、密钥生成与存储

4.1 经典蓝牙密钥(Link Key)

4.1.1 新链路密钥回调

cpp 复制代码
// src/adapter.c - 新链路密钥事件
static void new_link_key_callback(uint16_t index, uint16_t length,
                    const void *param, void *user_data)
{
    const struct mgmt_ev_new_link_key *ev = param;
    const struct mgmt_addr_info *addr = &ev->key.addr;
    struct btd_adapter *adapter = user_data;
    struct btd_device *device;
    
    if (length < sizeof(*ev)) {
        btd_error(adapter->dev_id, "Too small new link key event");
        return;
    }
    
    // 验证 PIN 长度
    if (ev->key.pin_len > 16) {
        btd_error(adapter->dev_id,
            "Invalid PIN length (%u) in new_key event", ev->key.pin_len);
        return;
    }
    
    device = btd_adapter_get_device(adapter, &addr->bdaddr, addr->type);
    if (!device)
        return;
    
    // 存储密钥(仅当 store_hint 为真时)
    if (ev->store_hint) {
        const struct mgmt_link_key_info *key = &ev->key;
        
        store_link_key(adapter, device, key->val, key->type, key->pin_len);
        device_set_bonded(device, BDADDR_BREDR);
    }
    
    bonding_complete(adapter, &addr->bdaddr, addr->type, 0);
}

4.1.2 链路密钥存储

cpp 复制代码
// src/adapter.c - 存储链路密钥
static void store_link_key(struct btd_adapter *adapter,
                struct btd_device *device, const uint8_t *key,
                uint8_t type, uint8_t pin_length)
{
    char device_addr[18];
    char filename[PATH_MAX];
    GKeyFile *key_file;
    char key_str[33];
    int i;
    
    // 获取设备地址字符串
    ba2str(device_get_address(device), device_addr);
    
    // 构造存储路径
    snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
            btd_adapter_get_storage_dir(adapter), device_addr);
    
    // 创建文件(权限 0600)
    create_file(filename, 0600);
    
    // 加载或创建键文件
    key_file = g_key_file_new();
    if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
        g_key_file_free(key_file);
        return;
    }
    
    // 转换密钥为十六进制字符串
    for (i = 0; i < 16; i++)
        sprintf(key_str + (i * 2), "%2.2X", key[i]);
    
    // 写入密钥信息
    g_key_file_set_string(key_file, "LinkKey", "Key", key_str);
    g_key_file_set_integer(key_file, "LinkKey", "Type", type);
    g_key_file_set_integer(key_file, "LinkKey", "PINLength", pin_length);
    
    // 保存到文件
    str = g_key_file_to_data(key_file, &length, NULL);
    g_file_set_contents(filename, str, length, NULL);
    g_free(str);
    
    g_key_file_free(key_file);
}

4.2 BLE 长期密钥(LTK)

4.2.1 LTK 存储

cpp 复制代码
// src/adapter.c - 存储 BLE LTK
static void store_longtermkey(struct btd_adapter *adapter,
                const bdaddr_t *peer, uint8_t bdaddr_type,
                const unsigned char *key, uint8_t central,
                uint8_t authenticated, uint8_t enc_size,
                uint16_t ediv, uint64_t rand)
{
    if (central != 0x00 && central != 0x01) {
        error("Unsupported LTK type %u", central);
        return;
    }
    
    if (central) {
        // Central 角色
        store_ltk_group(adapter, peer, bdaddr_type, key, 
                "LongTermKey", authenticated, enc_size, ediv, rand);
    } else {
        // Peripheral 角色
        store_ltk_group(adapter, peer, bdaddr_type, key,
                "PeripheralLongTermKey", authenticated,
                enc_size, ediv, rand);
    }
}

4.2.2 LTK 分组存储

cpp 复制代码
// src/adapter.c - LTK 分组存储
static void store_ltk_group(struct btd_adapter *adapter,
                const bdaddr_t *peer, uint8_t bdaddr_type,
                const unsigned char *key, const char *group,
                uint8_t authenticated, uint8_t enc_size,
                uint16_t ediv, uint64_t rand)
{
    char device_addr[18];
    char filename[PATH_MAX];
    GKeyFile *key_file;
    char key_str[33];
    int i;
    
    ba2str(peer, device_addr);
    
    // 构造存储路径
    snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
            btd_adapter_get_storage_dir(adapter), device_addr);
    
    key_file = g_key_file_new();
    g_key_file_load_from_file(key_file, filename, 0, NULL);
    
    // 转换密钥
    for (i = 0; i < 16; i++)
        sprintf(key_str + (i * 2), "%2.2X", key[i]);
    
    // 存储密钥信息
    g_key_file_set_string(key_file, group, "Key", key_str);
    g_key_file_set_integer(key_file, group, "Authenticated", authenticated);
    g_key_file_set_integer(key_file, group, "EncSize", enc_size);
    g_key_file_set_integer(key_file, group, "EDiv", ediv);
    g_key_file_set_uint64(key_file, group, "Rand", rand);
    
    // 保存
    create_file(filename, 0600);
    str = g_key_file_to_data(key_file, &length, NULL);
    g_file_set_contents(filename, str, length, NULL);
    g_free(str);
    
    g_key_file_free(key_file);
}

4.3 存储文件结构

4.3.1 经典蓝牙存储示例

cpp 复制代码
/var/lib/bluetooth/{adapter_addr}/{device_addr}/info
cpp 复制代码
[LinkKey]
Key=010203040506070809101112131415
Type=4
PINLength=16

4.3.2 BLE 存储示例

cpp 复制代码
[LongTermKey]
Key=010203040506070809101112131415
Authenticated=1
EncSize=16
EDiv=1234
Rand=1234567890

[IdentityResolvingKey]
Key=AABBCCDDEEFF00112233445566778899

[SignatureResolvingKey]
Key=112233445566778899AABBCCDDEEFF00
Counter=1

五、设备绑定完成处理

5.1 绑定完成回调

cpp 复制代码
// src/device.c - 设备绑定完成处理
void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
                            uint8_t status)
{
    struct bonding_req *bonding = device->bonding;
    struct authentication_req *auth = device->authr;
    struct bearer_state *state = get_state(device, bdaddr_type);
    
    DBG("bonding %p status 0x%02x", bonding, status);
    
    // 取消未完成的认证
    if (auth && auth->agent)
        agent_cancel(auth->agent);
    
    // 处理失败状态
    if (status) {
        device_cancel_authentication(device, TRUE);
        
        // 设备回到临时状态
        if (!device_is_paired(device, bdaddr_type) &&
                !device_is_trusted(device))
            btd_device_set_temporary(device, true);
        
        device_bonding_failed(device, status);
        return;
    }
    
    // 成功:清理认证请求
    device_auth_req_free(device);
    
    // 设置配对状态
    if (state->paired)
        return;  // 已配对,无需重复操作
    
    device_set_paired(device, bdaddr_type);
    
    // 如果服务已解析,直接回复
    if (state->svc_resolved && bonding) {
        store_gatt_db(device);  // 存储 GATT 数据库
        g_dbus_send_reply(dbus_conn, bonding->msg, DBUS_TYPE_INVALID);
        bonding_request_free(bonding);
        return;
    }
    
    // 启动服务发现
    if (bonding) {
        DBG("Proceeding with service discovery");
        
        // 移除发现定时器
        if (device->discov_timer) {
            timeout_remove(device->discov_timer);
            device->discov_timer = 0;
        }
        
        // 根据地址类型选择服务发现方式
        if (bdaddr_type == BDADDR_BREDR)
            device_browse_sdp(device, bonding->msg);   // SDP
        else
            device_browse_gatt(device, bonding->msg); // GATT
        
        bonding_request_free(bonding);
    } else if (!state->svc_resolved) {
        // 被动发现模式
        if (!device->browse && !device->discov_timer &&
                btd_opts.reverse_discovery) {
            // 启动延迟服务发现
            device->discov_timer = timeout_add(5000, 
                        delayed_discovery_cb, device, NULL);
        }
    }
}

5.2 状态机流转

六、经典蓝牙与 BLE 配对差异

6.1 核心差异对比

|--------|-------------------|-----------------------|
| 维度 | 经典蓝牙 (BR/EDR) | 低功耗蓝牙 (BLE) |
| 协议 | SSP(安全简单配对) | LE Secure Connections |
| 密钥类型 | Link Key | LTK(长期密钥) |
| 存储位置 | [LinkKey] 组 | [LongTermKey] 组 |
| 认证方式 | PIN 码、数字比较 | 数字比较、Just Works |
| 连接模式 | 主从模式 | Central-Peripheral |

6.2 密钥结构差异

6.2.1 BR/EDR Link Key

cpp 复制代码
// src/adapter.c - Link Key 类型
#define LINK_KEY_TYPE_COMBINATION    0x00  // 组合密钥
#define LINK_KEY_TYPE_LOCAL_UNIT     0x01  // 本地单元密钥
#define LINK_KEY_TYPE_REMOTE_UNIT    0x02  // 远端单元密钥
#define LINK_KEY_TYPE_DEBUG          0x03  // 调试密钥
#define LINK_KEY_TYPE_PAIRATION      0x04  // 配对密钥

6.2.2 BLE LTK 参数

cpp 复制代码
// src/adapter.c - LTK 存储参数
struct ltk_params {
    uint8_t key[16];        // 密钥值
    uint8_t authenticated;  // 是否认证
    uint8_t enc_size;      // 加密大小
    uint16_t ediv;          // 加密分隔符
    uint64_t rand;          // 随机数
};

6.3 配对流程差异

6.3.1 BR/EDR 配对

cpp 复制代码
1. 连接建立
2. 发送 Pair Device 命令
3. 协商 IO 能力
4. 验证方式:
   - 键盘输入 PIN 码
   - 显示数字进行比较
5. 生成 Link Key
6. 存储密钥
7. 建立加密链路

6.3.2 BLE 配对

cpp 复制代码
1. 连接建立
2. 发送 Pair Device 命令
3. 协商 LE 安全级别
4. 验证方式:
   - Just Works(无需验证)
   - 数字比较(6 位数字)
   - 密码输入(从设备输入)
5. 生成 LTK + IRK + CSRK
6. 存储密钥
7. 建立加密链路

七、常见问题与解决方案

7.1 配对失败问题

|---------|-------------|--------------|
| 问题 | 原因 | 解决方案 |
| PIN 码错误 | 用户输入不匹配 | 重新配对,确保输入正确 |
| 超时无响应 | 对端设备未响应 | 检查设备是否在范围内 |
| 不支持 SSP | 设备不支持安全简单配对 | 使用传统 PIN 码方式 |
| 加密失败 | 密钥协商出错 | 重启设备后重试 |

7.2 绑定丢失问题

|-----------|---------|------------|
| 问题 | 原因 | 解决方案 |
| 重启后需要重新配对 | 密钥未持久化 | 检查存储目录权限 |
| 连接时提示未配对 | 密钥损坏 | 删除绑定信息重新配对 |
| 多设备切换问题 | IRK 不匹配 | 清空所有绑定重新配对 |

7.3 调试技巧

cpp 复制代码
# 查看设备配对状态
bluetoothctl info AA:BB:CC:DD:EE:FF

# 查看已绑定设备列表
bt-device --list

# 启用详细日志
bluetoothd -d --verbose

# 查看存储的密钥文件
ls -la /var/lib/bluetooth/{adapter_addr}/

# 删除设备绑定
bt-device --remove AA:BB:CC:DD:EE:FF

八、核心函数索引

|-----------------------------------|---------------|----------------|
| 函数 | 文件 | 功能 |
| pair_device() | src/device.c | Pair DBus 方法处理 |
| adapter_create_bonding() | src/adapter.c | 创建绑定请求 |
| adapter_bonding_attempt() | src/adapter.c | 发送配对命令 |
| pair_device_complete() | src/adapter.c | 配对完成回调 |
| bonding_complete() | src/adapter.c | 绑定完成处理 |
| device_bonding_complete() | src/device.c | 设备绑定完成 |
| store_link_key() | src/adapter.c | 存储 BR/EDR 链路密钥 |
| store_longtermkey() | src/adapter.c | 存储 BLE LTK |
| store_ltk_group() | src/adapter.c | LTK 分组存储 |
| new_link_key_callback() | src/adapter.c | 新链路密钥事件 |
| user_passkey_request_callback() | src/adapter.c | PIN 码请求处理 |
| user_confirm_request_callback() | src/adapter.c | 数字比较处理 |

九、总结

蓝牙配对与绑定机制是一个涉及多模块协作的复杂过程:

  1. 协议层
  • 经典蓝牙使用 SSP(安全简单配对)

  • BLE 使用 LE Secure Connections

  1. 流程层
  • 配对触发:DBus 接口调用

  • 命令下发:通过 Management Interface

  • 交互验证:Agent 模块处理用户交互

  • 密钥存储:持久化到文件系统

  1. 安全层
  • 密钥类型:Link Key(BR/EDR)、LTK(BLE)

  • 存储路径:/var/lib/bluetooth/{adapter}/{device}/info

  • 文件权限:0600(仅所有者可读写)

理解蓝牙安全机制不仅有助于解决配对故障,更能为开发安全的蓝牙应用奠定基础。在实际工程中,需根据应用场景选择合适的配对方式和安全等级。

相关推荐
飞哥数智坊17 分钟前
当下 Agent 缺少的,也许是读懂产物的能力
人工智能
新知图书19 分钟前
14.1 多模态试驾预约Agent系统概述
人工智能·agent·ai agent·智能体
哦哦~92121 分钟前
AI赋能CFD:从Fluent仿真到物理信息机器学习的智能流体工程实战
人工智能·机器学习·cfd·fluent
QH1392923188023 分钟前
R&S FSPN50 FSPN26 FSWP26 相位噪声分析仪典型应用案例
人工智能·百度·微信·集成测试·音视频·facebook·oneapi
用户52746756142124 分钟前
给 Agent 一份 package-lock:别让 Skill、MCP 和权限各自漂移
人工智能
2601_9676598924 分钟前
2026信创深化落地期档案管理系统选型推荐:恒智科技综合档案管理系统
数据库·人工智能·科技
xx~t26 分钟前
嵌入式学习——进程与线程2
linux·c语言·学习·进程与线程
学习星球29 分钟前
6G核心网架构深度解析——AI Native时代的网络变革
网络·人工智能·5g·架构·go·信息与通信
吾在学习路29 分钟前
XSKILL: Continual Learning from Experience and Skills in Multimodal Agents
人工智能·深度学习·机器学习