xiaozhi/py-xiaozhi-main/documents/docs/guide/08_设备激活流程.md

324 lines
14 KiB
Markdown
Raw Permalink Normal View History

2025-07-18 13:14:28 +08:00
# 设备激活流程 v2
## 概述
当前流程是虾哥设备认证v2版本
## 激活流程
每个设备都有一个唯一的序列号(Serial Number)和HMAC密钥(HMAC Key),用于身份验证和安全通信。新设备首次使用时需要通过以下流程进行激活:
1. 客户端启动时向服务器发送设备信息包括序列号、MAC地址和客户端ID
2. 服务器检查设备是否已激活:
- 如果已激活,客户端正常工作
- 如果未激活服务器返回包含验证码和Challenge的激活请求
3. 客户端显示验证码提示用户前往xiaozhi.me网站输入验证码
4. 客户端使用HMAC密钥对Challenge进行签名并发送给服务器验证
5. 客户端通过轮询方式等待服务器确认验证结果:
- 如果验证成功,设备激活完成
- 如果验证失败或超时,设备激活失败
### 小智 ESP32 设备激活流程图
```
┌────────────────────┐
│ 设备启动 │
└──────────┬─────────┘
┌────────────────────┐
│ 初始化各组件 │
│ 连接WiFi/网络 │
└──────────┬─────────┘
┌────────────────────┐
│ 调用CheckVersion │
│ 访问OTA服务器 │──→ POST /xiaozhi/ota/
└──────────┬─────────┘
┌────────────────────┐
│ 解析服务器响应 │
└──────────┬─────────┘
┌─────┴─────┐
↓ ↓
┌─────────┐ ┌─────────┐
│是否有新版本│ │是否需要激活│
└─────┬───┘ └─────┬───┘
│ │
┌─────▼───┐ └───┬─── 否 ──┐
│升级固件 │ ↓ ↓
└─────────┘ ┌─────────────┐ ┌─────────────┐
│是否有激活码 │ │初始化协议连接│
└──────┬──────┘ │MQTT/WebSocket│
│ └─────────────┘
┌────▼───┐
│ 是 │
└────┬───┘
┌──────────────────┐
│显示激活码给用户 │
│播放语音提示 │
└────────┬─────────┘
┌──────────────────┐
│ 开始激活流程 │
└────────┬─────────┘
┌────────────────────────────────┐
│ 检查设备序列号 │
└───────────────┬────────────────┘
┌──────┴───────┐
↓ ↓
┌─────────┐ ┌─────────┐
│ 有序列号 │ │ 无序列号 │
└─────┬────┘ └────┬────┘
│ │
┌─────────▼────────┐ │
│构造激活载荷JSON: │ │
│- serial_number │ │
│- challenge │ │
│- hmac签名 │ │
└─────────┬─────────┘ │
│ │
└──────┬───────┘
┌───────────────────────┐
│发送POST请求到激活端点 │──→ POST /xiaozhi/ota/activate
└────────────┬──────────┘
┌───────────┴───────────┐
↓ ↓ ↓
┌─────────┐ ┌─────────┐ ┌─────────┐
│状态码200 │ │状态码202 │ │其他状态码│
│激活成功 │ │超时重试 │ │激活失败 │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
│ ┌────▼─────┐ │
│ │延迟后重试 │ │
│ │最多10次 │ │
│ └────┬─────┘ │
│ │ │
└───────────┼───────────┘
┌──────────────────┐
│设置激活状态标志位 │
└────────┬─────────┘
┌──────────────────┐
│ 继续正常运行 │
│ 连接MQTT/WS协议 │
└──────────────────┘
```
### 激活数据交互详细流程
```
┌────────────┐ ┌────────────┐ ┌────────────┐
│ │ │ │ │ │
│ 设备客户端 │ │ 服务器 │ │ 用户浏览器 │
│ │ │ │ │ │
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘
│ │ │
│ 请求设备状态 (MAC, ClientID, SN) │ │
│ ────────────────────────────────> │ │
│ │ │
│ 返回激活请求 (验证码, Challenge) │ │
<──────────────────────────────── │ │
│ │ │
│ 显示验证码 │ │
│ ┌─────────────┐ │ │
│ │请前往网站输入 │ │ │
│ │验证码: 123456│ │ │
│ └─────────────┘ │ │
│ │ │
│ │ 用户访问xiaozhi.me │
│ │ <─────────────────────────────────│
│ │ │
│ │ 输入验证码 123456 │
│ │ <─────────────────────────────────│
│ │ │
│ 计算HMAC签名 │ │
│ ┌─────────────┐ │ │
│ │ HMAC(密钥, │ │ │
│ │ Challenge) │ │ │
│ └─────────────┘ │ │
│ │ │
│ 发送激活请求 (SN, Challenge, 签名) │ │
│ ────────────────────────────────> │ │
│ │ ┌───────────────┐ │
│ │ │ 等待用户输入验证码 │ │
│ │ │ 超时返回202 │ │
│ │ └───────────────┘ │
│ │ │
│ 轮询等待 (HTTP Long Polling) │ │
│ ────────────────────────────────> │ │
│ HTTP 202 (Pending) │ │
<──────────────────────────────── │ │
│ │ │
│ 继续轮询... │ │
│ ────────────────────────────────> │ │
│ │ │
│ │ 验证码验证成功 │
│ │───────────────────────────────────│
│ │ │
│ 激活成功 (HTTP 200) │ │
<──────────────────────────────── │ │
│ │ │
│ ┌─────────────┐ │ │
│ │设备激活成功! │ │ │
│ └─────────────┘ │ │
│ │ │
```
## 设备与服务器通信内容详解
### 1. 设备信息请求 (POST /xiaozhi/ota/)
**请求头**:
```
Activation-Version: 2 // 表示支持序列号激活
Device-Id: AA:BB:CC:DD:EE:FF // MAC地址
Client-Id: xxxx-xxxx-xxxx-xxxx // 设备UUID
User-Agent: BOARD_NAME/1.0.0 // 开发板名称和固件版本
Content-Type: application/json
```
**请求体** (POST时):
```json
{
"version": 2,
"flash_size": 16777216,
"psram_size": 8388608,
"minimum_free_heap_size": 7265024,
"mac_address": "你的mac地址",
"uuid": "你的client_id",
"chip_model_name": "esp32s3",
"chip_info": {
"model": 9,
"cores": 2,
"revision": 0,
"features": 20
},
"application": {
"name": "xiaozhi",
"version": "1.6.0",
"compile_time": "2025-04-16T12:00:00Z",
"idf_version": "v5.3.2"
},
"partition_table": [
{
"label": "nvs",
"type": 1,
"subtype": 2,
"address": 36864,
"size": 24576
},
{
"label": "otadata",
"type": 1,
"subtype": 0,
"address": 61440,
"size": 8192
},
{
"label": "app0",
"type": 0,
"subtype": 0,
"address": 65536,
"size": 1966080
},
{
"label": "app1",
"type": 0,
"subtype": 0,
"address": 2031616,
"size": 1966080
},
{
"label": "spiffs",
"type": 1,
"subtype": 130,
"address": 3997696,
"size": 1966080
}
],
"ota": {
"label": "app0"
},
"board": {
"type": "lc-esp32-s3",
"name": "立创ESP32-S3开发板",
"features": ["wifi", "ble", "psram", "octal_flash"],
"ip": "你的ip地址",
"mac": "你的mac地址"
}
}
```
### 2. 服务器响应
**响应体**:
```json
{
"firmware": {
"version": "1.0.1",
"url": ""
},
"activation": {
"message": "请访问xiaozhi.me输入激活码",
"code": "123456",
"challenge": "randomstring123456",
"timeout_ms": 30000
},
"mqtt": {
"endpoint": "mqtt.xiaozhi.me",
"client_id": "device123",
"username": "user123",
"password": "pass123",
"publish_topic": ""
},
"websocket": {
"url": "wss://api.tenclass.net/xiaozhi/v1/",
"token": "test-token"
}
}
```
### 3. 设备激活请求 (POST /xiaozhi/ota/activate)
**请求体**:
```json
{
"Payload": {
"algorithm": "hmac-sha256",
"serial_number": "SN-5CD8467B47FB4920",
"challenge": "dac852d6-4ac4-4650-ba1a-c2a5bf00a766",
"hmac": "ada4775e3ed93cf9c0eb9ed00444138554ba416af41283a0e5603c77681a8022"
}
}
```
### 4. 激活响应
- **成功**: 状态码 200
- **等待用户输入验证码**: 状态码 202
- **失败**: 状态码 4xx (如401表示未授权400表示请求错误)
**响应体** (失败时):
```json
{
"error": "错误原因描述"
}
```
## 安全机制
设备激活流程v2版本采用以下安全机制
1. **设备唯一标识**:每个设备有一个唯一的序列号(Serial Number)
2. **HMAC签名验证**使用HMAC-SHA256算法对Challenge进行签名确保设备身份的真实性
3. **验证码验证**:通过要求用户在网页端输入验证码,防止自动化的激活攻击
4. **轮询等待机制**使用HTTP Long Polling等待服务器验证结果适应各种网络环境