2. 固件镜像哈希计算
任务目标
为OTA固件更新流程实现镜像完整性校验的基础环节:计算固件二进制镜像的SHA-256哈希值。本案例聚焦哈希计算本身,不涉及签名、加密或传输协议。
环境与依赖
- Python 3.8+(标准库
hashlib,无需第三方包) - 测试文件:任意二进制文件(如
firmware.bin),可用dd或truncate生成
关键完整代码
import hashlib
import sys
from pathlib import Path
CHUNK_SIZE = 64 * 1024 # 64KB,适配嵌入式镜像常见分块读取
def sha256_file(file_path: str) -> str:
"""计算文件的SHA-256哈希值,返回十六进制字符串。"""
h = hashlib.sha256()
with open(file_path, 'rb') as f:
while chunk := f.read(CHUNK_SIZE):
h.update(chunk)
return h.hexdigest()
def sha256_bytes(data: bytes) -> str:
"""计算内存中字节数据的SHA-256哈希值(用于小镜像或测试)。"""
return hashlib.sha256(data).hexdigest()
if __name__ == '__main__':
if len(sys.argv) != 2:
print('用法: python sha256_calc.py <firmware.bin>')
sys.exit(1)
path = sys.argv[1]
if not Path(path).is_file():
print(f'错误: 文件不存在 - {path}')
sys.exit(1)
digest = sha256_file(path)
print(f'SHA-256 ({path}) = {digest}')
运行与验证
- 生成测试镜像(1MB随机数据):
head -c 1048576 /dev/urandom > firmware.bin - 运行脚本:
python3 sha256_calc.py firmware.bin - 预期输出格式:
SHA-256 (firmware.bin) = <64位十六进制字符串>
验证方法
使用系统标准工具交叉校验,确认结果一致:
sha256sum firmware.bin
对比两个命令输出的64位十六进制字符串,完全一致即通过。若修改镜像任意一个字节(如 printf '\x01' | dd of=firmware.bin bs=1 seek=0 count=1 conv=notrunc),重新计算得到的哈希值应发生显著变化,用于确认哈希对镜像内容敏感。
常见问题
- 大文件内存溢出:代码采用分块读取(64KB),避免一次性加载整个镜像到内存,适用于数MB至数百MB的固件。
- 二进制模式:
open使用'rb'模式,防止Windows平台下换行符转换导致哈希值错误。 - 与OTA集成:实际OTA流程中,设备端(C语言)可用
mbedtls_sha256或wolfSSL实现相同算法;本案例的Python实现用于PC端生成参考哈希值或验证下载后镜像。