4. 设备身份与访问控制工程
影子读写是设备影子最核心的运行时行为:设备通过 update 上报状态、通过 get 拉取期望值,应用侧通过 update 下发期望、通过 get 读取上报。一旦身份与权限设计不到位,攻击者只要拿到一个设备凭证,就可能越权读取他人影子、伪造期望值下发,甚至批量接管设备。本章围绕“设备唯一标识—证书体系—令牌机制—最小权限策略”这条身份链,讲清在影子读写场景中如何真正落地。
一、设备唯一标识:身份链的根
设备唯一标识不是简单的“设备编号”,而是贯穿证书、令牌、策略、审计日志的主键。工程上通常采用三段式:产品标识(ProductKey/ProductID)+ 设备标识(DeviceName/SN)+ 实例标识(InstanceId)。产品标识区分设备型号与策略模板,设备标识区分同型号下的单台设备,实例标识用于区分同一物理设备在不同环境(生产/测试/灰度)中的身份,避免测试凭证流入生产。
标识生成必须满足三个约束:全局唯一、不可猜测、不可篡改。常见做法是设备出厂时由产线系统生成 128 位随机 DeviceSecret 或直接签发证书,SN 只作为人类可读的辅助标识,绝不作为鉴权依据。影子读写时,服务端从 TLS 客户端证书或令牌中提取标识,而不是信任报文里携带的 deviceId 字段——后者可被伪造。
二、证书体系:双向 TLS 是影子通道的底座
设备与影子服务之间推荐使用 mTLS(双向 TLS)。设备侧持有客户端证书与私钥,服务端持有服务端证书,双方在握手阶段互相验证。证书体系的关键参数包括:
- 密钥算法:优先 ECDSA P-256,资源受限设备可用 RSA-2048;
- 证书有效期:设备证书建议 1~2 年,配合轮换机制;
- 吊销机制:CRL 或 OCSP,设备被回收或私钥泄露时立即吊销;
- 证书链:设备证书 → 产品中间 CA → 根 CA,便于按产品批量吊销。
影子读写中,服务端在 TLS 层完成身份认证后,将证书中的 CN 或 SAN 映射为设备唯一标识,再进入授权判断。这样即使报文被篡改,攻击者也无法冒充其他设备,因为私钥不在其手中。
三、令牌机制:短时凭证与最小暴露面
对于资源受限或无法长期持有私钥的设备,可采用“长期身份 + 短期令牌”的两级机制:设备用证书或预置密钥向认证服务换取短期访问令牌(如 JWT),令牌中携带设备标识、权限范围、有效期(建议 5~60 分钟)。影子读写请求携带令牌,服务端验签并校验有效期与权限范围。
令牌设计要点:
- 签名算法:RS256 或 ES256,禁止
none; - 声明字段:
sub(设备标识)、scope(如shadow:read:self)、exp、jti(防重放); - 绑定:令牌与设备标识、TLS 会话或客户端指纹绑定,防止令牌被复制到其他设备使用;
- 刷新:短期令牌过期后用长期凭证刷新,刷新频率与吊销窗口需权衡。
四、最小权限策略:影子读写的授权模型
最小权限的核心是“默认拒绝、按需授予、按资源粒度收敛”。影子读写可抽象为四类操作:shadow:get:self、shadow:update:self、shadow:get:any、shadow:update:any。设备通常只应拥有前两者,且只能操作自己的影子;应用侧按业务角色授予后两者,并进一步限制到具体产品、设备组或字段路径。
策略表达可采用类似下面的结构(示例,非实测配置):
{
"version": "2024-01",
"statement": [
{
"effect": "allow",
"principal": "device:productA/device001",
"action": ["shadow:get:self", "shadow:update:self"],
"resource": "shadow:productA/device001",
"condition": {
"ipRange": "10.0.0.0/8",
"tlsClientCert": "required"
}
},
{
"effect": "deny",
"principal": "device:*",
"action": ["shadow:update:any"],
"resource": "*"
}
]
}
注意 deny 显式拒绝的优先级高于 allow,用于兜底防止越权。字段级最小权限还可进一步限制:设备只能上报 reported.temperature,不能写入 desired.firmwareUrl,避免设备伪造期望值触发恶意升级。
五、落地实践:一次影子读写的完整身份链
下面用一张图展示设备发起一次影子 update 时,身份与权限在各环节的传递与校验关系。图中左侧为设备侧,右侧为影子服务侧,中间为认证与授权组件。
图中可以看到,设备标识、证书、令牌、策略四者并非孤立,而是逐层收敛:证书解决“你是谁”,令牌解决“你能在什么时间窗口内做什么”,策略解决“你能对哪些资源做什么”。任何一层缺失,影子读写都会出现越权风险。
六、常见落地问题与判断依据
实践中,影子读写身份链最容易出问题的地方有三处。第一,标识与证书不一致:设备用 A 证书申请了 B 设备的令牌,服务端若只校验令牌签名而不校验 sub 与证书标识是否一致,就会越权。判断依据是审计日志中 deviceId 与证书 CN 是否匹配。第二,令牌有效期过长:超过 24 小时的令牌一旦泄露,吊销窗口过大。建议结合影子读写的实际频率,将有效期控制在分钟级,并用 jti 防重放。第三,策略粒度过粗:只授予 shadow:* 而不区分 self/any,设备可读写他人影子。判断依据是策略模拟测试:用设备凭证尝试 get 其他设备影子,应返回 403。
最后需要强调,影子读写的身份与访问控制不是一次性配置,而是随设备生命周期持续演进的工程能力。设备出厂、激活、轮换、回收、吊销,每个阶段都要有对应的标识与凭证操作,并与影子服务的授权策略保持同步。只有把唯一标识、证书、令牌、最小权限四者串成闭环,影子数据的安全才有可验证的底座。