4. 设备身份与唯一标识

设备身份这件事,说白了就是回答一个问题:「你怎么证明你是你?」

在IoT车队里,每台设备都要有一个不可伪造的身份证。我见过太多项目,设备身份就是写死在Flash里的一个UUID,或者用MAC地址凑合。结果呢?固件一读,身份全暴露;Flash一换,设备就「变脸」了。

真正的设备指纹,必须绑定硬件。今天我们就聊怎么用安全元件(SE)和可信执行环境(TEE)来生成靠谱的设备身份。

为什么软件方案靠不住?

先说说为什么不能只用软件。

我记得有个客户,设备里存了个RSA私钥,用AES加密后放在文件系统里。看起来挺安全对吧?结果攻击者通过UART接口dump了整个Flash,然后暴力破解了AES密钥——因为密钥派生用的salt是写死在代码里的。

软件方案有几个硬伤:

  • 密钥存储介质暴露:Flash、EEPROM都能被物理读取
  • 密钥生命周期不可控:谁生成、谁使用、谁销毁,全在CPU里
  • 无法防物理攻击:探针、激光、电压毛刺,都能撬开软件防线

所以,我们需要硬件级别的隔离。SE和TEE就是干这个的。

SE vs TEE:两种硬件信任根

先搞清楚概念。SE和TEE都是硬件隔离方案,但层级不同。

维度 安全元件(SE) 可信执行环境(TEE)
物理形态 独立芯片(eSE、SIM卡、SD卡) CPU内部隔离区(TrustZone、TEE OS)
安全等级 CC EAL5+ 以上,防物理破解 CC EAL2~EAL4,防软件攻击
密钥存储 芯片内部安全存储,不可导出 安全内存,受硬件保护
性能 慢(通常几十KB RAM) 快(共享主CPU资源)
成本 高(额外芯片+封装) 中(需要SoC支持)
典型场景 支付、车联网、高安全网关 生物识别、DRM、设备认证

我的建议是:能上SE就上SE。如果成本敏感,至少用TEE兜底。千万别裸奔。

基于SE的设备指纹生成流程

下面是我在项目中实际用过的方案。核心思路是:在SE内部生成密钥对,公钥作为设备指纹的一部分,私钥永不出SE。

核心原则:设备指纹 = 芯片唯一ID + SE内部公钥哈希 + 设备属性签名

具体步骤:

  1. 初始化阶段(产线)
    • SE上电,内部生成RSA-2048或ECC-P256密钥对
    • 读取芯片唯一ID(如MCU的UID、SE的UID)
    • 将芯片UID + SE公钥拼接,做SHA-256哈希
    • 用SE私钥对哈希值签名,得到设备证书
    • 将设备证书写入SE的安全存储区
  2. 运行阶段(设备上线)
    • 设备向云端发起注册请求
    • 携带:芯片UID、SE公钥、设备证书
    • 云端用SE公钥验证证书签名
    • 验证通过后,将设备指纹存入数据库
  3. 认证阶段(每次通信)
    • 设备生成随机数挑战
    • SE用私钥签名挑战值
    • 云端用公钥验签
    • 验签通过,确认设备身份

避坑指南:我曾经在产线上踩过一个坑——SE的密钥对生成太慢。ECC P-256大约需要2~3秒,RSA-2048要10秒以上。如果产线节拍是30秒一台,RSA根本来不及。后来我们改用ECC,并在产线预热阶段提前生成密钥对。

基于TEE的轻量级方案

如果预算有限,TEE是折中方案。我用过ARM TrustZone和Intel SGX,这里以TrustZone为例。

TEE方案的核心是:在安全世界(Secure World)中运行可信应用(TA),密钥存储在安全内存中,普通世界(Normal World)无法访问。

流程如下:

// 伪代码:TEE设备指纹生成
// 运行在Secure World

// 1. 读取硬件唯一ID
uint8_t chip_uid[16];
hal_read_chip_uid(chip_uid);

// 2. 在TEE内部生成密钥对
tee_key_handle_t key;
tee_generate_key(&key, TEE_ALG_ECC_P256);

// 3. 导出公钥
uint8_t pub_key[64];
tee_export_public_key(key, pub_key);

// 4. 计算指纹
uint8_t fingerprint[32];
sha256_context_t ctx;
sha256_init(&ctx);
sha256_update(&ctx, chip_uid, 16);
sha256_update(&ctx, pub_key, 64);
sha256_final(&ctx, fingerprint);

// 5. 用TEE私钥签名指纹
uint8_t signature[64];
tee_sign(key, fingerprint, 32, signature);

// 6. 返回给Normal World
// 注意:私钥永远不离开TEE
return (fingerprint, pub_key, signature);

注意:TEE方案有个致命弱点——如果攻击者通过电压毛刺或激光注入破坏了TEE的安全边界,密钥可能泄露。所以TEE适合中等安全场景,高安全场景必须上SE。

设备指纹的组成结构

一个完整的设备指纹,我建议包含以下字段:

字段 长度 说明
芯片UID 16字节 MCU或SE的出厂唯一ID
SE/TEE公钥 64字节(ECC) 设备身份的核心凭证
指纹哈希 32字节 SHA-256(UID + 公钥)
设备证书 128~256字节 指纹哈希的签名,用于验证
设备属性 可变 型号、固件版本、生产批次等

你想想看,如果攻击者想伪造这个指纹,他需要同时伪造芯片UID、SE公钥和证书签名。而SE私钥是物理不可克隆的,这就构成了硬件级别的信任根。

SVG:设备指纹生成与验证流程

设备指纹生成与验证流程 设备端(SE/TEE) ① 内部生成ECC密钥对 ② 读取芯片唯一UID ③ SHA-256(UID + 公钥) ④ 用私钥签名指纹哈希 输出:UID + 公钥 + 证书 云端验证 ⑤ 接收设备指纹数据 ⑥ 用公钥验证证书签名 ⑦ 比对指纹哈希一致性 ⑧ 存入设备指纹数据库 注册成功,返回设备Token TLS传输 私钥永不出SE/TEE,设备指纹不可伪造

产线实施要点

理论说完了,聊聊落地。产线实施是设备指纹方案最容易出问题的地方。

我经历过一次惨痛的教训:某批次5000台设备,SE密钥对生成时随机数种子出了问题,导致所有设备的私钥都相同。嗯,那批货全部报废。

几个关键点:

  • 随机数质量:SE内部必须有硬件TRNG,产线测试时要验证随机数分布
  • 密钥备份:SE私钥不可导出,但公钥和证书要备份到云端数据库
  • 产线节拍:ECC P-256生成约2秒,RSA-2048约10秒,选型时算好产能
  • 防重放:每个设备生成密钥对后,要写入「已初始化」标志,防止二次初始化

我的习惯:在产线最后增加一道「设备指纹验证」工序。用一台验证服务器,模拟云端注册流程,确认每台设备的指纹生成正确。这道工序能拦截90%以上的产线异常。

安全等级与选型建议

最后给个选型参考。根据设备的安全需求,我一般这样推荐:

安全等级 推荐方案 典型设备 成本增加
L1(基础) 软件+Flash加密 传感器、灯泡 ~$0.1
L2(中等) TEE(TrustZone) 智能音箱、网关 ~$0.5
L3(高) 独立SE芯片 车机、支付终端 ~$2~5
L4(极高) SE + TEE双保险 自动驾驶域控 ~$10+

说白了,安全是成本问题。没有绝对的安全,只有匹配业务风险的安全。

我个人习惯是:先定安全等级,再选方案,最后优化成本。千万别反过来——为了省两块钱,把整个车队的安全搭进去。