当前位置: 首页 > news >正文

手把手教你用Python脚本实现Keil编译后自动AES加密(附工程目录陷阱解析)

手把手教你用Python脚本实现Keil编译后自动AES加密(附工程目录陷阱解析)

在嵌入式开发中,固件升级是常见需求,而保障传输安全则是重中之重。AES加密因其高效可靠成为首选方案,但每次手动加密bin文件既耗时又容易出错。本文将带你用Python脚本实现Keil编译后自动完成AES加密的全流程,特别针对工程目录与脚本路径不一致这一"隐形杀手"提供完整解决方案。

1. 环境准备与基础配置

1.1 工具链检查

开始前请确保已安装:

  • Keil MDK(建议≥5.25)
  • Python 3.8+(需安装pycryptodome库)
  • 目标芯片的Device Family Pack

验证Python环境:

pip install pycryptodome python -c "from Crypto.Cipher import AES; print('AES模块可用')"

1.2 加密密钥管理

推荐采用.ini文件存储密钥,避免硬编码风险。示例config.ini:

[aes] key = 2B7E151628AED2A6ABF7158809CF4F3C iv = 000102030405060708090A0B0C0D0E0F

注意:实际项目中应通过密钥派生函数动态生成iv,此处简化演示

2. Python加密脚本开发

2.1 基础加密函数实现

创建aes_encryptor.py,核心代码如下:

from Crypto.Cipher import AES from Crypto.Util.Padding import pad import configparser def encrypt_file(input_path, output_path): config = configparser.ConfigParser() config.read('config.ini') key = bytes.fromhex(config['aes']['key']) iv = bytes.fromhex(config['aes']['iv']) cipher = AES.new(key, AES.MODE_CBC, iv) with open(input_path, 'rb') as f: plaintext = f.read() ciphertext = cipher.encrypt(pad(plaintext, AES.block_size)) with open(output_path, 'wb') as f: f.write(ciphertext)

2.2 增强型参数处理

改进版本支持命令行参数:

import sys import os if __name__ == "__main__": if len(sys.argv) != 3: print("Usage: python aes_encryptor.py <input_bin> <output_enc>") sys.exit(1) input_file = os.path.abspath(sys.argv[1]) output_file = os.path.abspath(sys.argv[2]) if not os.path.exists(input_file): print(f"Error: Input file {input_file} not found") sys.exit(2) encrypt_file(input_file, output_file) print(f"Success: Encrypted file saved to {output_file}")

3. Keil工程集成方案

3.1 编译后命令配置

在Keil中设置编译后自动执行:

  1. 打开Options for Target → User
  2. 在"After Build/Rebuild"勾选"Run #1"
  3. 输入命令:
python path/to/aes_encryptor.py ./Objects/your_firmware.bin ./Objects/encrypted.bin

关键参数说明:

参数说明示例值
%L工程文件路径C:/Projects/STM32
@L工程名称MyProject
.\工程所在目录-

3.2 目录陷阱解决方案

针对工程与脚本路径不一致问题,提供三种可靠方案:

方案一:绝对路径传递

python D:\scripts\aes_encryptor.py ^ %D\Objects\%@L.bin ^ %D\Objects\%@L_enc.bin

方案二:环境变量法

  1. 设置系统变量PY_SCRIPT_DIR
  2. Keil命令改为:
python %PY_SCRIPT_DIR%\aes_encryptor.py ...

方案三:批处理封装创建run_encrypt.bat

@echo off pushd "%~dp0" python aes_encryptor.py %* popd

Keil中调用:

cmd /c path/to/run_encrypt.bat ...

4. 调试与异常处理

4.1 常见错误排查表

现象可能原因解决方案
"python不是内部命令"Python未加入PATH使用完整python路径
找不到config.ini工作目录错误使用os.path.dirname(__file__)定位
加密文件为空源文件读取失败检查文件权限和路径
密钥错误.ini格式问题验证hex字符串长度

4.2 日志增强实践

在脚本中添加日志记录:

import logging logging.basicConfig( filename='encryption.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s' ) try: encrypt_file(input_file, output_file) except Exception as e: logging.error(f"加密失败: {str(e)}") raise

5. 进阶优化技巧

5.1 多线程加密加速

当需要批量处理时:

from concurrent.futures import ThreadPoolExecutor def batch_encrypt(file_pairs): with ThreadPoolExecutor() as executor: futures = [ executor.submit(encrypt_file, inp, out) for inp, out in file_pairs ] for future in futures: future.result() # 触发异常传播

5.2 固件校验机制

加密后添加CRC校验:

import zlib def add_crc(output_path): with open(output_path, 'rb+') as f: data = f.read() crc = zlib.crc32(data).to_bytes(4, 'big') f.write(crc)

实际项目中,我们团队发现最稳定的方案是方案三的批处理封装,配合日志记录可以快速定位90%以上的路径相关问题。当工程结构复杂时,建议在脚本初始处打印当前工作目录和参数解析结果,这对调试有极大帮助。

http://www.jsqmd.com/news/664055/

相关文章:

  • 京东抢购自动化终极指南:如何用JDspyder轻松抢到热门商品
  • 手把手教你用TensorFlow Lite在安卓端部署一个简单的关键词唤醒(KWS)模型
  • AI算力全解析:定义、数据与产业现状
  • Go语言的testing-quick随机测试与属性测试在函数契约验证中的使用
  • React 与 WebGPU:探索下一代图形接口在 React 数据可视化组件中的高性能集成
  • Golang reflect反射怎么用_Golang反射教程【通俗】
  • 终极指南:在Windows 10/11上直接安装Android应用的三种简单方法
  • ECharts图形标记全攻略:从内置形状到自定义SVG(最新版)
  • 智慧巡检-基于 YOLOv8 的轴承缺陷检测系统,实现从数据训练到多源检测、结果可视化的完整流程 YOLOV8预训练模型如何训练轴承缺陷检测数据集
  • 告别CPU搬运工:手把手教你用PL330 DMA指令集优化Exynos 4412数据传输
  • K8s Operator 的开发入门
  • 006、挑战:Transformer的算力之殇——注意力机制的二次方复杂度问题
  • 保姆级教程:用Thonny IDE给ESP32-CAM烧录MicroPython固件(含CH340驱动安装)
  • React Forget 编译器:深度分析自动化 Memoization 对 React 手动性能调优的革命性影响
  • 当Copilot遇上Git Rebase:智能生成代码冲突的8种反直觉模式(附可落地的Pre-Commit Hook检测清单)
  • PyTorch训练时遇到CUDA device-side assert错误?别慌,先检查你的标签和模型输出维度
  • 别再手动算堆栈了!STM32上这个自动检测方法,帮你省下80%调试时间
  • 终极视频修复指南:使用Untrunc快速拯救损坏的MP4/MOV文件 [特殊字符]
  • 【噪声控制】改进的灰狼优化算法和条件重初始化策略进行模型无主动噪声控制【含Matlab源码 15345期】
  • React 逻辑的可测试性:针对 React Hooks 的单体测试与渲染行为模拟的质量保障实践
  • 红外探测器硬件设计避坑指南:从电源滤波到防误报的五个关键细节
  • 告别僵硬图片!在Vue3的Quill编辑器中用quill-blot-formatter实现自由拖拽缩放
  • 开源鸿蒙 Flutter 实战|页面转场动画完整实现
  • Cadence Allegro PCB设计:5个必学的临时快捷键设置技巧(含旋转/翻转)
  • 中小公司预算有限,如何按IPDRR框架一步步搭建安全防线?从免费工具到开源方案实战指南
  • 深度解析:ABAP2XLSX技术架构与Excel报表生成优化
  • React 架构的可伸缩性:探讨从微型项目向大型单体 React 项目平滑演进的代码组织规范
  • SSC展频技术真能省个芯片?深入对比硬件SSCG与软件实现的优劣与选型
  • 2026年质量好的广东旋转气缸/广东自动化生产线夹持气缸多家厂家对比分析 - 行业平台推荐
  • 保姆级教程:在CentOS 7上从零部署RuoYi-Vue前后端分离项目(含Nginx+Tomcat10配置)