xiaozhi/py-xiaozhi-main/documents/docs/guide/08_设备激活流程.md
2025-07-18 13:14:28 +08:00

324 lines
14 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 设备激活流程 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等待服务器验证结果适应各种网络环境