64 lines
6.6 KiB
Markdown
64 lines
6.6 KiB
Markdown
# 首次认证、绑定与激活:实施说明
|
|||
|
|
|
||
|
|
更新:2026-09-12。设备契约 ONBOARDING-1.1,按用户要求移除 recovery_action、retry_after_ms、next_action。详细输入、输出和示例见[设备端接口](设备端注册绑定接口.md);完整操作见[字段清单](onboarding-api-fields.md)及[OpenAPI](../openapi/onboarding.yaml)。发布结果见[发布记录](onboarding-release-20260912.md)。
|
||
|
|
|
||
|
|
## 已实现功能
|
||
|
|
|
||
|
|
- 生产库存登记、MAC 唯一性、单设备独立密钥、工装加密交付、放行及凭据轮换。
|
||
|
|
- 专用 HTTP 校时、TIME1 响应签名、HTTPS 启动注册、DEVREQ1 请求签名和 Redis nonce 防重放。
|
||
|
|
- 临时设置会话、PKCE 一次性交接入口、OIDC 登录、家庭与使用者选择、手机申请及设备物理按键确认。
|
||
|
|
- 绑定事务、绑定代数、权限校验、持久化回执、双端 ACK 收尾、重启和断网恢复。
|
||
|
|
- 激活配置、设备 SDK 执行许可、结果上报、结果保存确认、首次通话和人工对账。
|
||
|
|
- 旧设备认证保留;解绑、隐私删除和凭据轮换使旧归属请求失效。
|
||
|
|
|
||
|
|
手机入口为 `/onboarding/entry#token=<handoff_token>&verifier=<verifier>`,由设备本地页面打开。手机临时流程为 `/onboarding/setup`,已绑定设备为 `/onboarding/devices`;生产登记和对账为 `/maintenance?area=onboarding`。
|
||
|
|
|
||
|
|
## 设备认证
|
||
|
|
|
||
|
|
C01 请求包含 device_id、key_version、boot_id、client_nonce,无请求时间戳或请求 HMAC。成功根对象直接返回 payload_b64、mac_hex。设备核验 `HMAC-SHA256(raw_device_key, "TIME1\n" + payload_b64)`,解码并核对本设备、本次启动及新随机数,再设置时间。包有效期120秒;固件还应执行原附件中的单调时钟往返限时、可信时间下限检查。
|
||
|
|
|
||
|
|
C02–C11 使用严格验证服务器证书的 HTTPS。DEVREQ1 九行使用 LF 分隔,末尾无换行:版本、方法、路径、设备编号、密钥版本、UTC毫秒、nonce、请求UUID、原始正文SHA256。完整签名规则以设备文档为准。
|
||
|
|
|
||
|
|
请求正文最大8KiB,拒绝多份JSON、重复字段、未知字段、缺少字段、null必填字段和非法UTF-8。设备请求不带query。版本及计数为0至2147483647,SDK返回码允许有符号32位整数。
|
||
|
|
|
||
|
|
业务重试保持请求UUID及原始正文不变,重新生成时间戳、nonce及签名。响应缓存同时检查当前启动、设备密钥、绑定代数、权限和原业务对象。C01不使用普通业务响应封装;其他成功外层为 `{ok,code,request_id,server_time_ms,data}`,失败为 `{ok,code,request_id,message}`。
|
||
|
|
|
||
|
|
## 绑定与收尾
|
||
|
|
|
||
|
|
手机申请不直接建立归属,C06真实按键确认后才提交绑定与激活任务。绑定变更提升同一条单调递增代数,旧请求不能恢复旧归属。
|
||
|
|
|
||
|
|
C07保存设备已接收状态。仅设备ACK时至少等待30秒;网页也ACK时从双方均完成起至少等待3秒。C07重复请求重新计算setup_can_close,但不延长原accepted_at。C11最终检查最新版本及关闭条件。
|
||
|
|
|
||
|
|
## 激活状态机
|
||
|
|
|
||
|
|
1. 绑定后,worker或C05准备加密配置;worker不会调用供应商注册。配置包含附件E.2字段,iot内是instance_id、product_key、product_secret、device_name。
|
||
|
|
2. C05激活命令仅返回config_b64、config_mac。设备验证CFG1 HMAC及包内设备、绑定代数、版本、到期时间。
|
||
|
|
3. 设备申请C08许可,平台在数据库持久化执行编号及30秒开始执行期限。未注册时对应SDK_REGISTER;已经注册并C10确认保存后对应CONVERSATION_TEST,不新增输入字段。
|
||
|
|
4. C09报告SUCCESS_OBSERVED、DEFINITE_FAILURE或UNKNOWN,阶段须匹配执行编号。UNKNOWN和到期未报结果均阻止新的不确定执行;仅许可过期不能当作失败。
|
||
|
|
5. 注册成功是物理设备事实,保留至解绑以后。C10确认结果保存,随后首通成功使当前绑定进入READY。重新绑定必须重新进行首通,不能使用上一代READY证明。
|
||
|
|
6. 配置有效期24小时,更新版本前确认没有不确定执行。相同绑定下续期配置ACK后可复用已记录的首通证明。
|
||
|
|
|
||
|
|
默认首通由设备SDK直接执行,C09携带设备认证后的观察结果。若首通走既有平台v3通话接口,则仍传原通话必填字段及intent=activation_test、activation_id、attempt_id,不需要permit_token;平台按关联会话核验开始、首音频、结束事件。每个执行编号最多关联一次会话。
|
||
|
|
|
||
|
|
C09不上传DeviceSecret。设备SDK生成的单设备凭据应按原文在设备本地保存。平台既有代管通话如需该密钥,仍使用原有预配或运维核验凭据机制;本次没有从精简接口推导新的密钥上传字段。
|
||
|
|
|
||
|
|
## 人工对账
|
||
|
|
|
||
|
|
需要ops_admin,填写任务版本、证据引用、处理原因。供应商注册结果不明时,核实注册成功用OBSERVED_REGISTERED;确认没有注册且已停止执行用CONFIRMED_NOT_REGISTERED。DeviceSecret是可选的既有平台凭据补录字段。DEVICE_ATTEMPT_STOPPED仅可释放已停止的首次通话尝试,不能借此跳过注册对账。许可到期后还需经过3分钟等待窗口,平台不会伪造供应商查询结果。
|
||
|
|
|
||
|
|
## 发布配置
|
||
|
|
|
||
|
|
数据库迁移000053至000058增加首次接入所需身份、会话、激活和回执记录;000052是原有设备重置计数迁移。
|
||
|
|
|
||
|
|
服务器使用原有compose.yaml、compose.override.yaml及compose.subtitle.yaml,再叠加[compose.onboarding.yaml](../deploy/server/compose.onboarding.yaml)。只更新API、worker、web及网关;原凭据和已有业务配置保留。ONBOARDING_MASTER_KEY_FILE指向服务器单独生成的64位hex主密钥文件。API和worker必须读取同一份主密钥和供应商产品配置。
|
||
|
|
|
||
|
|
ONBOARDING_ENABLED、ONBOARDING_ACTIVATION_ENABLED控制新流程;ONBOARDING_PAUSE_CLAIMS暂停新绑定申请。ONBOARDING_TRUSTED_PROXY_CIDRS应为实际网关Docker网段;ONBOARDING_ALLOW_LOCAL_HTTP在线上保持false。Nginx仅放行HTTP的C01,其余HTTP仍跳转HTTPS。
|
||
|
|
|
||
|
|
已有OIDC账号可以绑定。短信仅在配置真实发送通道后开启。自动创建账号的租户白名单默认空,按实际运营范围配置ONBOARDING_SELF_SIGNUP_TENANT_IDS。
|
||
|
|
|
||
|
|
## 验证
|
||
|
|
|
||
|
|
`go test ./...`、`go vet ./...`、`scripts/test-onboarding-integration.ps1`、`npm run generate:api`和`npm run build`均已通过。集成测试为各模块创建独立迁移数据库,不改本地业务数据库。覆盖设备11接口、按键绑定、跨代重放、未知结果、30秒许可、保存顺序、配置续期、直接SDK和既有SaaS会话路径。
|
||
|
|
|
||
|
|
测试中的SDK观察结果和短信是合成数据;实物按键、断电持久化及真实供应商SDK尚需设备端联调。
|