很多工程师把“安全”等同于“加密”,但在嵌入式系统中,安全的优先级通常是:
- 身份认证;
- 数据完整性;
- 数据保密性。
也就是说,设备首先要确认:
对方是否可信;
数据是否被改过;
数据内容是否需要隐藏。
只有前两个问题解决之后,保密性设计才有实际意义。
关键词 | 工程含义 |
|---|---|
认证 / 完整性 / 保密性 | 先确认对方可信和数据可信,再决定是否需要隐藏数据内容。 |
1. 为什么不能把安全简单理解为加密
在嵌入式系统中,很多人一提到安全,第一反应就是:
- 加 AES;
- 通信数据不要明文;
- 固件内容加密;
- 协议字段做混淆。
这些措施确实可以提高安全性,但它们并不等于完整的安全设计。
因为加密主要解决的是“别人能不能看懂数据”,而很多实际攻击并不是从“看懂数据”开始的,而是从下面这些问题开始的:
- 对方是不是合法设备?
- 这条命令是不是合法控制器发出的?
- 固件有没有被篡改?
- 配置参数有没有被偷偷修改?
- 这包数据是不是以前截获后重放的?
- 这个耗材、探头或电池是不是真的?
所以,在嵌入式安全中,通常应该先考虑身份认证和完整性,再考虑保密性。
2. 身份认证 Authentication
身份认证用于确认通信对象或设备确实是它声称的对象。
通俗地说,认证要解决的问题是:
你是谁?
你能不能证明你就是你?
在嵌入式产品中,认证常见于以下场景:
- 主机判断接入的传感器是否合法;
- 主机判断耗材、探头、电池是否为原厂或授权部件;
- 设备判断云端服务器是否可信;
- 设备判断升级包是否来自合法发布方;
- 网关判断接入的子设备是否可信;
- 产线系统判断设备是否为合法生产对象。
如果没有认证,攻击者可以伪造一个设备。
即使后续通信使用了加密,也可能只是和攻击者建立了一条**“加密但不可信”**的通道。
3. 没有认证时,加密也可能失效
一个常见误区是:
只要通信加密了,就安全了。
但如果设备没有先确认对方身份,加密通道本身也可能建立在错误对象之上。
例如:
主机通过某个接口连接传感器。如果攻击者伪造了一个传感器,并且主机没有认证机制,那么主机可能会直接和这个假传感器通信。
此时,即使通信过程中使用了 AES,结果也只是:
主机和假传感器之间建立了一条加密通道。
数据确实被加密了,但对方身份并不可信。
所以,认证是很多嵌入式安全设计中的第一步。
4. 完整性 Integrity
完整性用于判断数据是否被修改。
它要解决的问题是:
数据在传输、存储或升级过程中,有没有被改过?
在嵌入式系统中,需要完整性保护的数据很多,例如:
- 固件镜像;
- Bootloader;
- 配置参数;
- 校准参数;
- 控制命令;
- 日志记录;
- 测量数据;
- 生产序列号;
- 设备证书;
- 升级包元数据。
如果没有完整性保护,攻击者可能修改固件、配置或通信命令,从而让设备执行错误逻辑。
5. Hash、MAC 和数字签名的区别
完整性保护常见手段包括 Hash、MAC 和数字签名。
它们的作用不同,工程上不能混用。
方法 | 主要作用 | 是否能证明来源 | 典型用途 |
|---|---|---|---|
Hash | 判断数据有没有变化 | 不能 | 文件校验、固件摘要 |
MAC | 判断数据有没有变化,并证明发送方知道共享密钥 | 可以,前提是共享密钥安全 | 通信报文认证、挑战响应 |
数字签名 | 判断数据有没有变化,并证明来自私钥持有者 | 可以 | 固件签名、证书链、安全升级 |
5.1 Hash
Hash 可以发现数据变化。
例如,对固件计算 SHA-256 摘要,只要固件内容发生任何变化,摘要结果就会不同。
但 Hash 本身不能证明数据来自合法发送方。
原因是攻击者如果能够修改固件,也可以重新计算一个新的 Hash。
所以,Hash 更适合用于普通校验、摘要计算,不能单独作为安全认证手段。
5.2 MAC
MAC,也就是消息认证码。
它不仅能判断数据有没有被修改,还能证明发送方知道某个共享密钥。
例如,主机和设备内部都保存同一个密钥。发送方对消息计算 MAC,接收方用同一个密钥验证 MAC。
如果验证成功,说明:
- 数据没有被修改;
- 发送方大概率持有正确密钥。
因此,MAC 常用于设备认证、挑战响应和通信报文完整性保护。
5.3 数字签名
数字签名基于非对称密钥体系。
发布方使用私钥对固件或数据摘要进行签名,设备端使用公钥验证签名。
数字签名适合用于:
- 固件安全启动;
- OTA 升级包校验;
- 证书链验证;
- 生产授权文件验证。
它的优势是:设备端只需要保存公钥,不需要保存发布方私钥。
即使设备被攻击者拿到,也不应该能伪造合法签名。
6. 保密性 Confidentiality
保密性用于防止数据被窃听者读取。
它要解决的问题是:
这条数据被别人看到,会不会造成风险?
保密性适用于敏感数据,例如:
- 医疗数据;
- 用户身份信息;
- 密钥材料;
- 商业机密;
- 算法参数;
- 生产授权信息;
- 设备内部诊断数据;
- 某些专有协议内容。
常见保密性手段包括:
- 对称加密,例如 AES;
- 非对称加密;
- 会话密钥;
- TLS / DTLS;
- 安全存储;
- 加密 Flash;
- 加密升级包。
7. 不是所有数据都必须加密
不是所有命令都必须加密。
例如:
打开灯;
查询版本号;
读取普通状态;
设置非敏感工作模式。
这些数据内容本身可能并不敏感,即使被别人看到,风险也不大。
但是,这并不代表它们不需要安全保护。
对于控制命令来说,更重要的问题通常是:
- 命令是不是合法控制器发出的?
- 命令有没有被篡改?
- 命令是不是历史数据重放?
- 命令是否在允许的权限范围内?
也就是说,有些数据不一定需要保密性,但一定需要认证、完整性和防重放保护。
8. 工程判断方法
判断一条消息是否需要加密时,不要先问:
能不能加 AES?
而应该先问三个问题:
8.1 这条消息需要证明来源吗?
如果需要证明来源,就要考虑:
- 设备认证;
- 消息认证;
- 挑战响应;
- MAC;
- 数字签名;
- 证书机制。
8.2 这条消息被篡改会不会有风险?
如果被篡改会造成风险,就要考虑:
- 完整性校验;
- MAC;
- 数字签名;
- 安全计数器;
- 防回滚;
- 防重放机制。
8.3 这条消息内容被别人看到是否有价值?
如果内容被看到会造成风险,就要考虑:
- 数据加密;
- 会话密钥;
- 密钥协商;
- 安全存储;
- TLS / DTLS;
- 加密升级包。
前两个问题通常决定认证和完整性,第三个问题才决定保密性。
9. 工程示例
示例 1:固件升级包
固件升级包通常至少需要:
- 完整性保护;
- 发布方身份认证;
- 防回滚机制。
如果固件内容涉及算法、协议或商业机密,还需要考虑加密。
也就是说,固件升级包并不是“只加密”就安全,关键是要验证:
这个固件是不是官方发布的?
这个固件有没有被篡改?
这个固件是不是允许安装的版本?
示例 2:耗材认证
耗材认证的核心通常不是“数据是否保密”,而是:
这个耗材是不是真的?
它是不是被复制出来的?
它有没有被重复使用或非法复位?
因此,耗材认证通常需要:
- 唯一身份;
- 挑战响应;
- 共享密钥或非对称认证;
- 安全计数器;
- 防重放机制。
示例 3:普通控制命令
例如“打开灯”这样的命令,内容本身并不敏感。
但是,如果攻击者可以伪造这条命令,系统仍然存在风险。
所以它可以不加密,但应该保证:
- 命令来自合法控制器;
- 命令没有被篡改;
- 命令不是历史数据重放;
- 命令在当前状态下允许执行。
10. 工程总结
加密只是安全的一部分。
真正可靠的嵌入式安全系统,必须先解决两个更基础的问题:
- 身份可信;
- 数据可信。
然后再根据数据价值决定是否需要隐藏内容。
简单来说:
认证解决“你是谁”;
完整性解决“数据有没有被改”;
保密性解决“别人能不能看懂”。
在嵌入式产品中,安全设计的优先级通常不是:
先加密,再考虑其他。
而应该是:
先认证身份;
再保护完整性;
最后根据需要保护保密性。