主题
接口通信安全
涉及子系统:云端 API、小程序、管理后台、工控机 核心业务:保障各端与云端 API 之间通信的身份认证、授权、数据完整性与传输加密
零信任安全原则
本系统所有通信链路均基于以下零信任核心原则设计:
- 默认拒绝:任何请求在未完成身份验证与授权前,一律不信任,不区分来源是内网还是外网
- 持续验证:每次请求独立校验身份与权限,上一次合法不代表这次合法
- 最小权限:每个身份只能访问其当前任务所需的最小资源集合
- 假设已突破:设计时假设令牌可能被盗、通道可能被监听,通过多层防御降低爆炸半径
- 全程审计:所有关键操作留存不可篡改日志,支持事后追溯
安全机制总览
| 通信链路 | 传输层 | 身份认证 | 授权模型 | 附加防护 |
|---|---|---|---|---|
| 用户端小程序 → 云端 API | TLS 1.3 + 域名固定 | JWT(微信登录签发,RS256) | 服务端权限查询 | — |
| 店长端小程序 → 云端 API | TLS 1.3 + 域名固定 | JWT(微信登录签发,RS256) | 服务端权限查询 | HMAC-SHA256 全量请求签名 |
| 客服后台 → 云端 API | TLS 1.3 + HSTS | JWT(账号密码 + TOTP 2FA) | 服务端权限查询 | HMAC-SHA256 全量请求签名 |
| 工控机 → 云端 API(HTTP) | TLS 1.3 + 域名固定 | SN_Secret HMAC 签名 | 设备身份 + 接口白名单 | X-Request-ID 去重、nonce 时间窗 |
| 工控机 ↔ 云端(MQTT) | TLS(IoT Explorer,腾讯云 CA) | IoT Explorer 设备认证(DeviceSecret / 设备证书,按实例配置) | Topic 级 ACL | msg_id 幂等去重、timestamp 时间窗校验 |
MQTT 通道首期使用腾讯云 IoT Explorer 的托管连接能力,只承载平台无关 JSON 消息透传、在线状态与 Topic 权限;业务授权、门禁策略、审计、幂等和重试仍由客户 Backend 与 IPC 应用层负责。
用户体系设计
系统面向三类参与方,每类使用独立的用户表和独立的 ID 体系,互不影响:
| 用户体系 | 数据表 | ID 前缀 | 使用端 | 说明 |
|---|---|---|---|---|
| 消费者 | consumer | c_ | 用户端小程序 | 健身房会员 |
| 教练 | coach | h_ | 教练端(规划中) | 课程宣讲者 |
| 管理人员 | staff | s_ | 店长端小程序、客服后台 | 客服、店长、财务、运营、老板等 |
设计原则:
- 系统隔离:同一个自然人可以同时是消费者、教练和管理人员,分别拥有三个独立账号(如
c_001、h_001、s_001),登录入口不同,权限不交叉 - 封禁隔离:封禁消费者账号不影响其教练身份或管理身份,反之亦然
- 独立演进:每个体系可以独立扩展字段、规则和业务流程,不互相牵制
- 自然人关联(可选):三套体系通过手机号 / 微信 openid 可做松耦合关联,仅用于运营分析,不作为权限依据
管理人员角色
管理人员表内部通过 role 字段区分角色,角色决定可访问的功能范围:
| 角色 | 说明 | 门店范围 |
|---|---|---|
owner | 老板 | 名下所有门店 |
ops | 运营 | 分配的门店 |
finance | 财务 | 分配的门店 |
manager | 店长 | 分配的门店 |
support | 客服 | 分配的门店 |
一个管理人员的门店权限通过
staff_store关联表(staffId+storeId)维护,不写入 JWT。
客户端 → 云端安全设计
一、身份认证
1.1 用户端小程序登录
用户端小程序 wx.login()
│
▼ code(5分钟有效)
云端 API /auth/consumer/wx-login
│ code + appId + appSecret → 微信服务器
▼ openid + session_key
在 consumer 表中查找或创建记录
│
▼
签发 JWT(Access Token + Refresh Token)
返回给小程序,存储于 wx.setStorage- 云端不存储
session_key,仅在签名校验时使用后丢弃 - 首次登录检测:若 openid 无对应消费者,创建
consumer记录,引导绑定手机号 - 用户端仅使用 JWT 鉴权,无需附加 HMAC 请求签名
1.2 店长端小程序登录
店长端小程序 wx.login()
│
▼ code(5分钟有效)
云端 API /auth/staff/wx-login
│ code + appId + appSecret → 微信服务器
▼ openid
在 staff 表中查找(openid 须已绑定管理账号,否则拒绝登录)
│
▼
签发 JWT + 下发 clientSecret(HMAC 签名密钥)- 店长端不自动创建账号——管理人员账号必须由上级在后台预创建并绑定微信
clientSecret随登录响应下发一次,客户端存入wx.setStorageSyncclientSecret用于后续所有请求的 HMAC 签名(见 1.5 节)
1.3 客服后台登录
- 提交账号 + 密码(bcrypt 哈希校验)
- 校验通过后要求输入 TOTP 动态码(Google Authenticator 协议)
- 两步均通过后签发 JWT,同时下发
clientSecret
客服后台账号必须开启 2FA,系统强制校验——无 TOTP 的账号无法完成登录。
1.4 登录入口隔离
三套用户体系使用不同的登录 API 路径,互不可达:
| 端 | 登录接口 | 查询的表 |
|---|---|---|
| 用户端小程序 | POST /auth/consumer/wx-login | consumer |
| 店长端小程序 | POST /auth/staff/wx-login | staff |
| 客服后台 | POST /auth/staff/password-login | staff |
| 教练端(规划中) | POST /auth/coach/wx-login | coach |
二、JWT 规范
Token 结构
JWT 只携带身份标识,不携带角色和门店等权限数据:
json
{
"sub": "c_abc123",
"iss": "consumer",
"iat": 1712345678,
"exp": 1712352878
}| 字段 | 说明 |
|---|---|
sub | 用户 ID(含体系前缀:c_ / h_ / s_) |
iss | 签发来源,标识用户体系:consumer / coach / staff |
iat | 签发时间 |
exp | 过期时间 |
轻量 JWT 的核心意义:
- JWT 体积固定(约 200 字节),不随门店数量、角色复杂度膨胀
- 角色和门店权限在服务端查询(Redis 缓存),变更即时生效——无需等 Token 过期
- 同一个
staffId被分配新门店后,下一个请求立即有权限,不需要重新登录
有效期策略
| 用户体系 | Access Token | Refresh Token |
|---|---|---|
consumer | 2 小时 | 30 天 |
coach | 2 小时 | 30 天 |
staff | 1 小时 | 7 天 |
- 算法:RS256(私钥签发在云端,公钥可分发校验)
- Refresh Token 单次使用(Rotation):使用后立即废弃,同时签发新 Refresh Token
- 检测到 Refresh Token 复用(已废弃的 Token 被提交)→ 判定令牌泄露,立即吊销该账号所有活跃 Token,强制重新登录
Token 吊销
以下情况立即吊销该账号所有活跃 Refresh Token(写入 Redis 黑名单,TTL = Token 最长有效期):
- 主动退出
- 密码/绑定手机号变更
- 上级强制下线
- 检测到 Refresh Token 复用攻击
- 账号被封禁
封禁
consumer表中的某用户,只吊销iss=consumer的 Token;该自然人若同时拥有staff身份,不受影响。
三、请求授权(每次请求均校验)
云端 API 网关对每个入站请求执行以下验证链:
① 提取 Authorization: Bearer <token>
② 验证 JWT 签名(RS256 公钥)
③ 验证 token 未过期(exp)
④ 检查 token 是否在吊销黑名单中(Redis)
⑤ 从 token 提取 sub(用户ID)和 iss(用户体系)
⑥ 验证 iss 与当前 API 路由所属系统匹配(consumer 端 token 不能访问 staff 端接口)
⑦ 从 Redis 加载该用户的权限上下文(role + 门店列表 + 功能权限)
⑧ 验证 role 有权访问当前接口
⑨ 如涉及 storeId,验证该门店在用户的门店列表内
⑩ 通过 → 处理业务逻辑任意步骤失败均返回 401 Unauthorized 或 403 Forbidden,不透露具体失败原因。
权限上下文缓存
每次请求在步骤 ⑦ 中加载的权限上下文来自 Redis(而非 JWT),结构示例:
消费者(无门店概念,权限固定):
json
{
"id": "c_abc123",
"system": "consumer",
"status": "active"
}管理人员(角色 + 门店列表从 Redis 读取):
json
{
"id": "s_xyz789",
"system": "staff",
"role": "manager",
"storeIds": ["store-001", "store-003"],
"status": "active"
}- 缓存 TTL:5 分钟,变更时主动失效
- 权限变更(角色调整、门店分配变更、封禁)时立即清除对应 key,下次请求重新从 DB 加载
owner角色的storeIds可能很大(上万家店),Redis 中使用 Set 结构存储,权限校验用SISMEMBER查询,O(1) 复杂度
管理人员权限矩阵
| 功能 | support | manager | finance | ops | owner |
|---|---|---|---|---|---|
| 查看门店设备状态 | ✅ | ✅ | ❌ | ✅ | ✅ |
| 控制设备(开门、开淋浴) | ✅ | ✅ | ❌ | ✅ | ✅ |
| 查看门店消费记录 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 封禁/解封消费者 | ❌ | ✅ | ❌ | ✅ | ✅ |
| 门店配置变更 | ❌ | ✅ | ❌ | ✅ | ✅ |
| 查看/导出财务报表 | ❌ | ❌ | ✅ | ✅ | ✅ |
| 管理人员账号管理 | ❌ | ❌ | ❌ | ❌ | ✅ |
| 门店创建 / 角色分配 | ❌ | ❌ | ❌ | ❌ | ✅ |
所有涉及
storeId的操作,服务端从 Redis 读取该staffId的门店列表进行校验,不依赖客户端传参。
四、传输安全
协议要求
- 强制 TLS 1.3,服务端拒绝 TLS 1.2 及以下版本的握手
- 仅启用以下密码套件:
TLS_AES_256_GCM_SHA384TLS_CHACHA20_POLY1305_SHA256
小程序域名固定
在微信小程序 app.json 中配置合法请求域名,并在请求层封装统一检查:
- 所有
wx.request调用统一走封装函数,硬编码允许的 host 列表 - 域名变更需同步更新小程序版本并重新审核
管理后台响应头安全
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Content-Security-Policy: default-src 'self'; connect-src 'self' https://api.fitron-system.com
Referrer-Policy: strict-origin-when-cross-origin五、HMAC 请求签名(店长端 + 客服后台 + 工控机)
店长端小程序和客服后台的所有请求均附加 HMAC 签名(用户端小程序不需要),工控机同样使用 HMAC 签名但采用不同密钥和 Header 约定:
5.1 店长端 + 客服后台
X-Timestamp: {Unix秒}
X-Nonce: {16字节随机串,hex编码}
X-Signature: HMAC-SHA256(
method + ":" + path + ":" + timestamp + ":" + nonce + ":" + SHA256(requestBody),
clientSecret
)云端验证规则:
|serverTime - timestamp| ≤ 60 秒(防重放时间窗口)nonce在 60 秒窗口内未使用过(Redis SETNX,TTL 120 秒)- 重算签名与
X-Signature一致
clientSecret 生命周期:
- 登录时由云端生成并下发一次
- 服务端以
staffId为 key 存于 Redis - 用户退出登录或 Token 吊销时同步删除
- 重新登录时生成新的
clientSecret
5.2 工控机(SN_Secret 签名)
X-SN: {设备SN}
X-Request-ID: {UUID v4}
X-Timestamp: {Unix秒}
X-Nonce: {32位随机hex}
X-Signature: HMAC-SHA256(
uppercase(SN) + ":" + timestamp + ":" + nonce + ":" + requestBody,
SN_Secret
)requestBody 不允许包含换行;参与签名前去除首尾空格。GET 请求 requestBody 为空字符串。
与店长端/客服后台的差异:
| 维度 | 店长端/客服后台 | 工控机 |
|---|---|---|
| 身份标识 | JWT sub | X-SN |
| 密钥 | clientSecret(登录下发) | SN_Secret(出厂烧录) |
| 附加 Header | 无 | X-SN、X-Request-ID |
| 时间窗 | ≤ 60 秒 | ≤ 300 秒 |
| Nonce 去重窗口 | 60 秒 | 10 分钟 |
工控机不使用 JWT,不签发 Bearer 会话,每个请求独立签名验签。
六、速率限制
| 接口 | 限制规则 | 触发后行为 |
|---|---|---|
/auth/consumer/wx-login | 同 IP 10次/分钟 | 锁定该 IP 15 分钟 |
/auth/staff/password-login(密码) | 同账号 5次失败/10分钟 | 账号锁定 30 分钟,发送告警 |
/auth/staff/password-login(TOTP) | 同账号 3次失败/10分钟 | 会话终止,需重新输入密码 |
| 人脸识别接口 | 同 consumerId 10次/分钟 | 429 Too Many Requests |
| 开门接口 | 同 consumerId 5次/分钟 | 429 Too Many Requests |
| 全局 API(单用户) | 500次/分钟 | 429 Too Many Requests,记录异常日志 |
七、异常检测与告警
| 场景 | 检测条件 | 响应措施 |
|---|---|---|
| Refresh Token 复用 | 已吊销的 Refresh Token 被提交 | 吊销该账号所有 Token,强制重登 |
| 同账号多地并发活跃 | 同用户 5 分钟内从 3 个不同 IP 活跃 | 触发人工审核告警,可配置强制下线 |
| 异常高频请求 | 单用户触发全局速率限制 | 记录异常事件,临时封禁账号 |
| JWT 校验失败率突增 | 同 IP JWT 校验失败率 > 20%/分钟 | 自动封禁该 IP 1 小时,告警 |
| 非工作时间管理操作 | staff 在配置的工作时间外执行高风险操作 | 发送告警通知,操作需二次确认 |
| 跨体系异常关联 | 同一手机号在短时间内触发多个体系的安全事件 | 标记为高风险自然人,通知运营 |
八、敏感数据处理
| 数据类型 | 传输 | 存储 | 展示 |
|---|---|---|---|
| 手机号 | TLS 加密 | AES-256-GCM + KMS | 脱敏:138****1234 |
| 人脸特征向量 | TLS + AES-256-GCM 应用层加密 | AES-256-GCM + KMS,与 consumerId 解耦存储 | 不展示,仅用 faceId 引用 |
| 身份证号 | TLS 加密 | AES-256-GCM + KMS | 脱敏:3101**********1234 |
| 支付信息 | TLS 加密 | 不落地,直接转发支付平台 | 仅展示末四位 |
响应数据最小化:API 响应中只返回调用方身份对应体系且当前业务必需的字段,多余字段在序列化层过滤。
九、审计日志
以下操作记录不可篡改的审计日志(追加写入,不支持修改/删除):
| 操作类型 | 记录字段 |
|---|---|
| 登录 / 退出 | userId(含体系前缀), ip, userAgent, timestamp, result |
| 开门操作 | userId, storeId, deviceId, msg_id, timestamp |
| 消费扣款 | consumerId, orderId, amount, operatorId, timestamp |
| 人脸注册 / 删除 | consumerId, operatorId, faceId, timestamp |
| 管理配置变更 | staffId, changeType, before, after, timestamp |
| Token 吊销 | userId, reason, operatorId, timestamp |
| 账号封禁 / 解封 | targetId, operatorId, reason, timestamp |
日志写入后只允许追加,审计日志库使用独立存储,与业务数据库隔离。
工控机零信任安全架构
工控机安全链路按 SN_Secret + IoT 连接凭证 双密钥模型组织:
SN_Secret:用于工控机、Centre、客户私有云之间的签名验签和设备身份确认。IoT 连接凭证:用于工控机接入腾讯云 IoT Explorer MQTT 通道。fcc-api.fitron.vip:仅负责首次寻址与跨云密钥同步,运行期不参与控制流。
工控机与云端有两条独立通信链路,采用“引导身份 + 业务身份 + 设备通信身份”三层模型:
| 通信链路 | 可控程度 | 安全机制 |
|---|---|---|
| 引导与业务 API(工控机直连 Centre / 客户 Backend) | 完全可控,服务端由飞创或客户私有云部署 | TLS 1.3 + 域名固定 + SN_Secret HMAC 签名 |
| MQTT(经 IoT Explorer 中转) | 托管可控,Broker 由腾讯云托管 | IoT Explorer 设备认证(按实例支持 DeviceSecret 或证书) + TLS |
IoT Explorer 在本方案中作为设备消息总线,不承担业务授权。租户归属、设备策略、下发权限以 Centre + 客户 Backend 为权威来源。
威胁模型
| 威胁 | 引导/API 通道防护 | MQTT 通道防护 |
|---|---|---|
| 中间人窃听 / 篡改 | TLS 1.3 + 域名固定 + HMAC 签名 | IoT Explorer TLS(腾讯云 CA) |
| 仿冒工控机接入 | SN_Secret 签名 + nonce + 时间窗 | IoT Explorer 设备认证(DeviceSecret / 证书) |
| 仿冒云端欺骗工控机 | 只访问预置 Centre 域名和已下发的客户私有云 URL | 工控机校验 IoT Explorer 服务端证书链 |
| WiFi 劫持安装恶意证书 | 域名白名单 + TLS 证书校验 + 应用层签名 | 同左 |
| 远程代码执行 | 只处理结构化 JSON,不执行脚本/二进制 | 同左 |
| 物理拆机窃取凭证 | SN_Secret 本地加密存储 + 调试口封禁 | IoT 连接凭证本地加密存储 |
| 指令重放攻击 | X-Request-ID + nonce + 时间窗校验 + HMAC | msg_id 幂等去重 + timestamp 时间窗 |
| IoT Explorer 侧消息泄露 | 不适用(API 不经 IoT Explorer) | MQTT 仅承载控制与状态,不承载人脸等敏感信息 |
一、设备上线前提与 TPM 支持确认
为避免纸面支持但交付不支持,工控机采购和验收阶段必须先确认 TPM 能力。
1)采购与出厂验收标准(必须)
| 检查项 | 目标要求 | 结论判定 |
|---|---|---|
| 厂商规格书 | 明确标注 TPM 2.0(Discrete/Firmware TPM) | 未标注即不纳入可交付型号 |
| BIOS/UEFI | Security 页面可见 TPM/PTT/fTPM 开关 | 无开关视为高风险型号 |
| OS 识别 | 系统可识别 TPM 设备并读取能力信息 | 识别失败不得入库 |
| 持久化测试 | 重启后 PCR/持久句柄可正常读取 | 不稳定视为不合格 |
2)到货后现场验证命令(Ubuntu 22.04,定昌 A576)
bash
ls /dev/tpm* && tpm2_getcap properties-fixed && tpm2_getcap algorithms- 有
/dev/tpm0或/dev/tpmrm0且tpm2_getcap正常返回,判定系统层可用。 - 若命令不存在,先安装
tpm2-tools后复测。
3)Ubuntu 22.04 交付验收记录(必须留档)
- 留存 BIOS/UEFI 中 TPM/PTT/fTPM 已开启的照片或验收截图。
- 留存
tpm2_getcap properties-fixed输出,记录 TPM 厂商、版本、算法能力。 - 留存重启后复测记录(至少 3 次),确认设备重启后 TPM 仍可访问。
若定昌 A576 某批次不支持 TPM 2.0,可降级使用加密分区 + 文件私钥方案,但需在客户风险清单中明确标注为"中风险机型"并限制部署范围。
二、双密钥体系
| 凭证 | 作用链路 | 来源 | 存储与轮换要求 |
|---|---|---|---|
SN | 设备公开标识 | 出厂写入 | 可明文存储,需与设备资产记录一致 |
SN_Secret | Centre 寻址、客户私有云报到、HTTP 上行签名 | 出厂受控写入,Centre 密文托管 | 工控机本地加密存储;Centre 与客户私有云侧使用 KMS/HSM 或等效密钥保护 |
| IoT 连接凭证 | MQTT 长连接认证 | 客户私有云调用 IoT Explorer 动态创建 | 工控机本地加密存储;禁用设备时同步禁用 IoT 侧设备 |
SN_Secret 不进入 MQTT payload,不在小程序、管理后台或日志中展示。客户私有云完成跨云同步后,后续工控机 HTTP 请求均由本地数据库/Redis 中的 SN_Secret 完成验签。
三、IoT Explorer 设备认证(MQTT 通道)
首期使用腾讯云 IoT Explorer 企业实例,MQTT 通道认证方式按实例能力最终定稿,可为 DeviceSecret 或设备证书:
| 凭证 | 来源 | 说明 |
|---|---|---|
ProductID | IoT Explorer 控制台 | 产品标识,全局唯一 |
DeviceName | 与 ipcId 一致 | 设备标识 |
DeviceSecret / DeviceCert + DevicePrivateKey | 客户私有云调用 IoT Explorer 设备注册接口获取 | 每台设备独立身份材料 |
MQTT CONNECT 认证:工控机使用 ProductID、DeviceName,并按实例配置的 DeviceSecret 或 DeviceCert / DevicePrivateKey 与 IoT Explorer 建立 TLS 连接完成认证。
明确的安全边界:
- 工控机 → IoT Explorer 这段链路由 TLS 加密保护,外部无法窃听
- IoT Explorer 内部可以读取 MQTT 报文明文(这是托管 Broker 的固有特征)
- 我们的 MQTT 报文中不包含需要对腾讯云保密的数据(指令、设备状态、传感器读数均为业务操作数据,非用户隐私)
- 敏感数据(人脸特征向量等)不走 MQTT,走 HTTPS 通道并做应用层加密
四、出厂预置初始化
工控机在发货前于内部受控环境(办公室/仓库)统一完成初始化,写入所有程序与安全凭证。现场部署人员只做物理安装与网络接入,不接触任何安全材料。
初始化写入内容
| 写入内容 | 用途 | 说明 |
|---|---|---|
| 操作系统镜像 | — | 精简定制 Linux,关闭不必要服务和端口 |
| 工控机应用程序 | — | 含设备驱动、MQTT 客户端、HTTP 上报模块 |
| OTA 升级程序 | — | 负责后续远程固件/程序更新 |
SN | 设备标识 | 与 Centre 资产池一致 |
SN_Secret | HTTP 签名 | 出厂受控写入,工控机本地加密存储 |
| Centre 固定地址 | 首次寻址 | fcc-api.fitron.vip |
| IoT 连接凭证 | MQTT 认证 | 首次注册后由客户私有云下发并落盘 |
/etc/fitron/config.json | 两者 | 静态配置与运行期注册结果(ipcId、storeId、ProductID、MQTT Broker 地址、API 地址等) |
初始化流程
五、设备上线时序
安全要点:
- Centre 服务地址固定为
fcc-api.fitron.vip - 所有寻址、报到、配置拉取请求必须带 nonce、时间戳与 HMAC 签名
SN_Secret与 IoT 连接凭证必须加密落盘,不进入日志- 初始化操作留存完整操作日志(操作人、设备序列号、时间),归入审计记录
- 设备发货后,
ipcId状态在云端为"待激活";首次完整上线成功后自动激活
六、HTTP 通道签名认证
工控机直连 Centre 和客户 Backend 的 HTTP 通道强制使用 TLS 1.3,并在应用层使用 SN_Secret 做 HMAC 签名。
工控机 → 云端方向:
- 工控机只访问预置 Centre 域名和 Centre 返回的客户私有云 URL。
- 每次请求携带
SN、X-Request-ID、X-Timestamp、X-Nonce、X-Signature。 - 请求体参与摘要计算,服务端按本地
SN_Secret重算签名。 - 服务端校验 nonce 未使用、时间窗有效、设备状态未冻结。
TLS 配置要求:
| 参数 | 要求 |
|---|---|
| 最低 TLS 版本 | TLS 1.3 |
| 密码套件 | TLS_AES_256_GCM_SHA384 / TLS_CHACHA20_POLY1305_SHA256 |
| 服务端证书 | 完整链校验,域名必须匹配 |
| 应用层签名 | SN_Secret HMAC-SHA256 |
七、HTTP 请求签名格式
工控机每次 HTTP 请求携带以下 Header,供服务端做身份比对、日志追踪和请求去重:
X-SN: FT-A1B2C3D4-9F2E
X-IPC-ID: ipc-store001(激活后携带)
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000
X-Timestamp: 1768617100
X-Nonce: a1b2c3d4e5f67890a1b2c3d4e5f67890
X-Signature: HMAC-SHA256(uppercase(SN):timestamp:nonce:body, SN_Secret)| Header | 说明 |
|---|---|
X-SN | 出厂设备标识,用于定位 SN_Secret |
X-IPC-ID | IPC 标识,设备激活后携带 |
X-Request-ID | UUID v4,每次请求唯一,用于日志追踪和幂等去重(Redis 缓存,TTL 10 分钟) |
X-Timestamp | Unix 秒,服务端校验时间窗 |
X-Nonce | 32 位随机 hex,服务端通过 Redis 去重 |
X-Signature | 请求签名,覆盖 uppercase(SN)、timestamp、nonce 和 body |
签名原文格式:uppercase(SN) + ":" + TIMESTAMP + ":" + NONCE + ":" + BODY
SN:与X-SN一致,参与签名时转为大写TIMESTAMP:与X-Timestamp一致NONCE:与X-Nonce一致BODY:请求体原始字符串;GET 请求为空字符串""BODY约束:不允许包含换行;参与签名前去除首尾空格- 签名输出:64 位小写 hex
身份认证以
SN_Secret签名为主;涉及注册、凭证下发、远程控制等高风险接口必须同时校验设备状态和门店归属。
八、MQTT Topic ACL
腾讯云 IoT Explorer 支持设备级 Topic 权限控制:
| deviceName | 可 SUBSCRIBE | 可 PUBLISH |
|---|---|---|
FT-A1B2C3D4-9F2E | A0VYTK4W4F/FT-A1B2C3D4-9F2E/data | (无;上行经 HTTPS) |
- 每台工控机只能订阅自己的
dataTopic - 不能读写其他工控机的 Topic(即使知道其他
deviceName) - 客户私有云以管理员身份发布到
{ProductID}/{deviceName}/data
九、指令防伪与完整性(MQTT 应用层)
MQTT 通道的传输安全由 IoT Explorer TLS 保障,应用层通过以下机制保证指令真实性:
- 时间窗校验:工控机收到指令后,校验
timestamp与本地时间差 ≤ 300 秒,超出则丢弃(防重放) - 幂等去重:
msg_id记录在本地有序集合中(保留最近 1000 条),重复msg_id不重复执行 - 指令白名单:工控机只处理协议文档中定义的
type,其他一律回执result:{target}:{action}且data.result=unsupported - data 强校验:每种
type对应严格的 JSON Schema,不符合 Schema 的data拒绝执行
工控机永远不会解析或执行
data中的代码、脚本、Shell 命令或二进制数据。所有操作均为预定义的结构化动作。
十、工控机远程禁用
管理员需要紧急禁用某台工控机时,需同时操作两条通道:
| 步骤 | API 通道 | MQTT 通道 |
|---|---|---|
| ① | 将 SN / ipcId 状态置为 disabled | 在 IoT Explorer 禁用对应设备 |
| ② | 后续 HTTP 签名请求被拒绝 | IoT Explorer 强制断开 MQTT 连接 |
| ③ | 记录禁用原因、操作人和时间 | 后续 MQTT CONNECT 被拒绝 |
恢复条件:需由具备权限的管理员重新启用设备,并重新下发或确认 IoT 连接凭证。
十一、工控机指令下发前置安全检查链
云端在处理"向工控机下发指令"的请求时,按顺序执行:
① 验证调用方身份与权限(JWT + RBAC + storeIds 归属校验)
② 验证目标 ipcId 对应门店在调用方 storeIds 范围内
③ 查询 IoT Explorer 设备在线状态
④ 查询目标 deviceId 的 connectionState(是否 disabled)
⑤ 设备在线且未禁用 → 生成 `msg_id`,构造指令,发布到 MQTT
⑥ 启动 10 秒回执超时定时器任意步骤失败均拒绝操作,返回对应错误码。
十二、数据分流原则
根据两条通道的安全特性,对数据进行分流:
| 数据类型 | 走 HTTPS(SN_Secret 签名) | 走 MQTT(IoT Explorer) |
|---|---|---|
| 设备控制指令(开门、开灯等) | ✅ | |
| 指令回执 | ✅ | |
| 设备状态上报 | ✅ | |
| 设备事件上报 | ✅ | |
| 人脸特征向量(加密后) | ✅ | |
| OTA 升级包下载 | ✅ | |
| IoT 连接凭证下发 | ✅ | |
| 门店配置下发 | ✅ |
原则:操作类指令走 MQTT(利用其实时双向通道特性),敏感数据和大文件走 HTTPS(使用
SN_Secret签名、TLS 和应用层加密保护)。
待确认事项
- [ ]
SN_Secret本地加密存储方案:文件加密、安全芯片或 TPM 封装 - [ ] Centre 与客户私有云侧
SN_Secret的 KMS/HSM 保护和审计规则 - [ ] IoT 连接凭证禁用、重发、轮换的接口与人工审批规则
- [ ] 审计日志的存储选型:云数据库追加写、专用日志平台,或两者并用
- [ ] 非工作时间管理操作告警的时间范围配置粒度:全局统一还是门店级独立配置