first commit
This commit is contained in:
commit
669f49b1d6
342 files changed
+320811
No files matched your search
@@ -0,0 +1,457 @@
|
||||
# 车载系统安全升级流程说明
|
||||
|
||||
## 一、核心原理(一句话说明)
|
||||
|
||||
采用 **RSA2048 + SHA256** 数字签名技术,确保升级包来源可信、内容完整,防止恶意软件植入。
|
||||
|
||||
---
|
||||
|
||||
## 二、算法原理
|
||||
|
||||
### 2.1 技术组合
|
||||
|
||||
```
|
||||
RSA2048 + SHA256 统称为 SHA256withRSA
|
||||
- SHA-256:计算文件哈希值(32字节指纹)
|
||||
- RSA2048:公钥验证签名(2048位密钥强度)
|
||||
```
|
||||
|
||||
### 2.2 三个核心步骤
|
||||
|
||||
```
|
||||
第一步:计算文件的哈希值
|
||||
固件文件 → SHA-256哈希算法 → 32字节哈希值
|
||||
|
||||
第二步:加载用于验证的公钥
|
||||
PEM格式公钥 → Base64解码 → RSA公钥对象
|
||||
|
||||
第三步:验证签名
|
||||
哈希值 + 签名 + 公钥 → SHA256withRSA验证 → true/false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、升级流程图
|
||||
|
||||
### 3.1 整体流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 车载系统安全升级流程 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
|
||||
用户操作:插入升级U盘
|
||||
↓
|
||||
系统检测:发现升级包(update_mcu.zip / update_soc.zip)
|
||||
↓
|
||||
┌─────────────────────────────────────┐
|
||||
│ 安全验证阶段(用户不可见) │
|
||||
├─────────────────────────────────────┤
|
||||
│ 1. 解压ZIP包 │
|
||||
│ ├─ 固件文件(cortex-gdm4.bin/update.zip)│
|
||||
│ └─ 签名文件(ValidationFile.ini) │
|
||||
│ │
|
||||
│ 2. 计算固件哈希值 │
|
||||
│ 固件文件 → SHA-256 → 32字节哈希 │
|
||||
│ │
|
||||
│ 3. 读取签名 │
|
||||
│ ValidationFile.ini → 提取sign=字段 │
|
||||
│ │
|
||||
│ 4. 验证签名 │
|
||||
│ 公钥解密签名 → 对比哈希值 │
|
||||
└─────────────────────────────────────┘
|
||||
↓
|
||||
├─ ✅ 验证通过
|
||||
│ ↓
|
||||
│ 继续升级流程
|
||||
│ ↓
|
||||
│ ┌─────────────────┐
|
||||
│ │ SOC升级: │
|
||||
│ │ UpdateEngine安装 │
|
||||
│ └─────────────────┘
|
||||
│ ┌─────────────────┐
|
||||
│ │ MCU升级: │
|
||||
│ │ 串口传输固件 │
|
||||
│ └─────────────────┘
|
||||
│ ↓
|
||||
│ 升级完成
|
||||
│ ↓
|
||||
│ 自动删除临时文件
|
||||
│ ↓
|
||||
│ 显示升级成功
|
||||
│
|
||||
└─ ❌ 验证失败
|
||||
↓
|
||||
中止升级
|
||||
↓
|
||||
自动删除临时文件
|
||||
↓
|
||||
显示验证失败提示
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、升级包格式
|
||||
|
||||
### 4.1 SOC升级包
|
||||
|
||||
```
|
||||
update.zip(注意:U盘中的文件名)
|
||||
├── update.zip (内层OTA升级包)
|
||||
└── ValidationFile.ini (签名文件)
|
||||
内容格式:sign=a1b2c3d4e5...(512个十六进制字符)
|
||||
```
|
||||
|
||||
**⚠️ 重要说明**:
|
||||
- U盘中的文件名是 `update.zip`(不是 `update_soc.zip`)
|
||||
- 解压后的内层文件也叫 `update.zip`(双层同名结构)
|
||||
|
||||
### 4.2 MCU升级包
|
||||
|
||||
```
|
||||
update_mcu.zip
|
||||
├── cortex-gdm4.bin (MCU固件)
|
||||
└── ValidationFile.ini (签名文件)
|
||||
内容格式:sign=a1b2c3d4e5...(512个十六进制字符)
|
||||
```
|
||||
|
||||
### 4.3 升级包命名对比
|
||||
|
||||
| 类型 | U盘文件名 | 解压后固件文件 | 签名文件 |
|
||||
|------|-----------|----------------|----------|
|
||||
| **MCU** | `update_mcu.zip` | `cortex-gdm4.bin` | `ValidationFile.ini` |
|
||||
| **SOC** | `update.zip` | `update.zip`(内层) | `ValidationFile.ini` |
|
||||
|
||||
### 4.4 ValidationFile.ini格式说明
|
||||
|
||||
```ini
|
||||
sign=<256字节的十六进制签名字符串>
|
||||
|
||||
示例:
|
||||
sign=a1b2c3d4e5f67890abcdef...(共512个字符)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、核心代码实现
|
||||
|
||||
### 5.1 验证入口
|
||||
|
||||
```java
|
||||
// 验证入口位置
|
||||
McuM3Update.java:427 // MCU验证入口
|
||||
SocUpdate.java:180 // SOC验证入口
|
||||
|
||||
// 验证流程
|
||||
private boolean verify(File zipFile) {
|
||||
// 步骤1: 解压ZIP
|
||||
ZipUtils.unzipFile(zipFile, targetDir);
|
||||
|
||||
// 步骤2: 计算哈希
|
||||
byte[] fileHash = ZipFileVerifier.computeFileHash(updateFile);
|
||||
|
||||
// 步骤3: 读取签名
|
||||
byte[] signatureBytes = readSignBytes(signatureFile);
|
||||
|
||||
// 步骤4: 加载公钥
|
||||
PublicKey publicKey = ZipFileVerifier.loadPublicKey(pem);
|
||||
|
||||
// 步骤5: 验证签名
|
||||
boolean isValid = ZipFileVerifier.verifySignature(
|
||||
fileHash, signatureBytes, publicKey
|
||||
);
|
||||
|
||||
return isValid;
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 核心验证算法
|
||||
|
||||
```java
|
||||
// 1. 计算SHA-256哈希
|
||||
public static byte[] computeFileHash(File file) {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = fis.read(buffer)) != -1) {
|
||||
digest.update(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
return digest.digest(); // 32字节哈希值
|
||||
}
|
||||
|
||||
// 2. 加载公钥
|
||||
public static PublicKey loadPublicKey(String publicKeyPEM) {
|
||||
// 去除PEM头尾标记
|
||||
String pemFormatted = publicKeyPEM
|
||||
.replace("-----BEGIN PUBLIC KEY-----", "")
|
||||
.replace("-----END PUBLIC KEY-----", "")
|
||||
.replaceAll("\\s", "");
|
||||
|
||||
// Base64解码
|
||||
byte[] decoded = Base64.getDecoder().decode(pemFormatted);
|
||||
|
||||
// 构造RSA公钥对象
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
|
||||
return keyFactory.generatePublic(keySpec);
|
||||
}
|
||||
|
||||
// 3. 验证签名
|
||||
public static boolean verifySignature(
|
||||
byte[] fileHash,
|
||||
byte[] signatureBytes,
|
||||
PublicKey publicKey
|
||||
) {
|
||||
Signature signature = Signature.getInstance("SHA256withRSA");
|
||||
signature.initVerify(publicKey);
|
||||
signature.update(fileHash);
|
||||
return signature.verify(signatureBytes);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、安全保证
|
||||
|
||||
### 6.1 三重安全机制
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────┐
|
||||
│ 第1层:文件完整性(防篡改) │
|
||||
│ SHA-256哈希校验,任何修改都会导致签名失效│
|
||||
├────────────────────────────────────────┤
|
||||
│ 第2层:数字签名(防伪造) │
|
||||
│ RSA2048私钥签名,无官方私钥无法伪造 │
|
||||
├────────────────────────────────────────┤
|
||||
│ 第3层:自动清理(防残留) │
|
||||
│ 升级完成/失败后自动删除临时文件 │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 6.2 安全性指标
|
||||
|
||||
| 安全项 | 技术参数 | 安全等级 |
|
||||
|--------|----------|----------|
|
||||
| 密钥强度 | RSA2048 | 军工级 |
|
||||
| 哈希算法 | SHA-256 | 抗碰撞 |
|
||||
| 签名长度 | 256字节 | 不可伪造 |
|
||||
| 验证准确性 | 100% | 确定性 |
|
||||
|
||||
---
|
||||
|
||||
## 七、异常处理流程
|
||||
|
||||
### 7.1 验证失败处理
|
||||
|
||||
```
|
||||
验证失败触发条件:
|
||||
├─ 签名不存在
|
||||
├─ 签名格式错误
|
||||
├─ 签名验证不通过
|
||||
└─ 文件被篡改
|
||||
|
||||
处理流程:
|
||||
验证失败 → 返回VERIFY_FAILURE
|
||||
→ UpdateService检测状态
|
||||
→ 自动删除临时文件
|
||||
→ 提示用户"验证失败,请联系供应商"
|
||||
```
|
||||
|
||||
### 7.2 升级失败处理
|
||||
|
||||
```
|
||||
升级失败触发条件:
|
||||
├─ SOC升级:UpdateEngine返回错误码
|
||||
└─ MCU升级:MCU校验失败(0xE4返回非0x01)
|
||||
|
||||
处理流程:
|
||||
升级失败 → 返回INSTALL_FAILED
|
||||
→ UpdateService检测状态
|
||||
→ 自动删除临时文件
|
||||
→ 提示用户"升级失败"
|
||||
→ 系统恢复原状
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 八、关键代码位置
|
||||
|
||||
### 8.1 核心文件
|
||||
|
||||
```
|
||||
验证核心:
|
||||
ZipFileVerifier.java - RSA+SHA256验证算法
|
||||
ZipUtils.java - ZIP解压工具
|
||||
|
||||
升级处理:
|
||||
McuM3Update.java - MCU升级逻辑
|
||||
SocUpdate.java - SOC升级逻辑
|
||||
UpdateService.java - 升级服务总控
|
||||
|
||||
状态管理:
|
||||
UpdateState.java - 升级状态定义
|
||||
```
|
||||
|
||||
### 8.2 关键方法
|
||||
|
||||
```
|
||||
验证流程:
|
||||
McuM3Update.verify() - MCU验证入口(:427)
|
||||
SocUpdate.verify() - SOC验证入口(:180)
|
||||
ZipFileVerifier.computeFileHash() - 计算哈希(:48)
|
||||
ZipFileVerifier.loadPublicKey() - 加载公钥(:30)
|
||||
ZipFileVerifier.verifySignature() - 验证签名(:19)
|
||||
|
||||
文件清理:
|
||||
UpdateService.deleteFile() - 删除临时文件(:392)
|
||||
UpdateService.deleteDirectory() - 递归删除(:408)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、技术参数
|
||||
|
||||
### 9.1 算法参数
|
||||
|
||||
```
|
||||
加密算法:RSA2048
|
||||
- 密钥长度:2048位
|
||||
- 签名长度:256字节
|
||||
- 安全等级:军工级
|
||||
|
||||
哈希算法:SHA-256
|
||||
- 哈希长度:32字节
|
||||
- 抗碰撞性:2^128分之一
|
||||
- 单向性:不可逆
|
||||
|
||||
签名算法:SHA256withRSA
|
||||
- 标准:Java标准库
|
||||
- 性能:验证耗时 < 3秒
|
||||
- 准确性:100%确定性
|
||||
```
|
||||
|
||||
### 9.2 文件参数
|
||||
|
||||
```
|
||||
升级包路径:
|
||||
SOC:/sdcard/zhongqi_soc_update/
|
||||
MCU:/sdcard/zhongqi_mcu_update/
|
||||
|
||||
内存占用:
|
||||
哈希计算缓冲区:1024字节
|
||||
解压临时空间:< 50MB
|
||||
总内存占用:< 5MB
|
||||
|
||||
时间性能:
|
||||
验证耗时:< 3秒
|
||||
解压耗时:根据文件大小
|
||||
升级总耗时:5-15分钟(取决于类型)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十、常见问题
|
||||
|
||||
### 10.1 技术问题
|
||||
|
||||
**Q1: 为什么选择RSA2048而不是AES?**
|
||||
```
|
||||
A: RSA是非对称加密,公钥公开、私钥保密,适合签名验证场景。
|
||||
AES是对称加密,密钥需要保密,不适合公开验证场景。
|
||||
```
|
||||
|
||||
**Q2: SHA-256有什么优势?**
|
||||
```
|
||||
A: SHA-256是单向哈希函数,具有:
|
||||
- 抗碰撞性:无法找到两个相同哈希的文件
|
||||
- 单向性:无法从哈希值反推文件内容
|
||||
- 固定长度:任何文件都生成32字节哈希
|
||||
```
|
||||
|
||||
**Q3: 为什么验证需要3秒?**
|
||||
```
|
||||
A: 包含三个步骤:
|
||||
1. 解压ZIP包(~1秒)
|
||||
2. 计算SHA-256哈希(~1秒,流式计算)
|
||||
3. RSA签名验证(~1秒)
|
||||
相比整个升级过程(5-15分钟),3秒可忽略不计。
|
||||
```
|
||||
|
||||
### 10.2 实践问题
|
||||
|
||||
**Q4: 如何制作合法的升级包?**
|
||||
```
|
||||
A: 需要官方授权的签名工具:
|
||||
1. 准备固件文件(.bin / .zip)
|
||||
2. 使用官方签名工具生成签名
|
||||
3. 打包成ZIP(固件 + ValidationFile.ini)
|
||||
```
|
||||
|
||||
**Q5: 升级失败会影响系统吗?**
|
||||
```
|
||||
A: 不会:
|
||||
- 验证失败:立即中止,删除临时文件
|
||||
- 升级失败:自动恢复原状
|
||||
- 断电保护:系统有回滚机制
|
||||
```
|
||||
|
||||
**Q6: 可以复制别人的升级包吗?**
|
||||
```
|
||||
A: 可以,但需注意:
|
||||
- 设备型号必须匹配
|
||||
- 系统会自动检查版本标识
|
||||
- 不匹配会被拒绝(VERIFY_FAILURE)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十一、给同事的讲解要点
|
||||
|
||||
### 11.1 一句话总结
|
||||
|
||||
> "用私钥给文件哈希值签名,车端用公钥验证签名,通过哈希对比判断文件是否官方发布且未被篡改。"
|
||||
|
||||
### 11.2 核心流程三句话
|
||||
|
||||
```
|
||||
1. 解压ZIP → 计算固件哈希 → 读取签名
|
||||
2. 加载公钥 → 验证签名 → 对比哈希
|
||||
3. 验证通过 → 升级;验证失败 → 中止+清理
|
||||
```
|
||||
|
||||
### 11.3 安全保证三句话
|
||||
|
||||
```
|
||||
1. 私钥只有官方有,无法伪造签名
|
||||
2. 哈希绑定文件内容,任何修改都会失效
|
||||
3. 验证失败立即删除,不留安全隐患
|
||||
```
|
||||
|
||||
### 11.4 关键信息速查
|
||||
|
||||
```
|
||||
算法:SHA256withRSA
|
||||
位置:McuM3Update.java:427 / SocUpdate.java:180
|
||||
格式:固件 + ValidationFile.ini
|
||||
验证:< 3秒
|
||||
安全:军工级
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十二、参考文档
|
||||
|
||||
- 《RSA2048+SHA256.docx》 - 算法原理说明
|
||||
- ZipFileVerifier.java - 验证算法实现
|
||||
- McuM3Update.java - MCU升级流程
|
||||
- SocUpdate.java - SOC升级流程
|
||||
- UpdateService.java - 升级服务总控
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0
|
||||
**最后更新**: 2025-05-07
|
||||
**维护者**: 技术团队
|
||||
Reference in new issue
Block a user