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

张开发
2026/4/19 4:01:24 15 分钟阅读

分享文章

手把手教你用Python脚本实现Keil编译后自动AES加密(附工程目录陷阱解析)
手把手教你用Python脚本实现Keil编译后自动AES加密附工程目录陷阱解析在嵌入式开发中固件升级是常见需求而保障传输安全则是重中之重。AES加密因其高效可靠成为首选方案但每次手动加密bin文件既耗时又容易出错。本文将带你用Python脚本实现Keil编译后自动完成AES加密的全流程特别针对工程目录与脚本路径不一致这一隐形杀手提供完整解决方案。1. 环境准备与基础配置1.1 工具链检查开始前请确保已安装Keil MDK建议≥5.25Python 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(fError: Input file {input_file} not found) sys.exit(2) encrypt_file(input_file, output_file) print(fSuccess: Encrypted file saved to {output_file})3. Keil工程集成方案3.1 编译后命令配置在Keil中设置编译后自动执行打开Options for Target → User在After Build/Rebuild勾选Run #1输入命令python path/to/aes_encryptor.py ./Objects/your_firmware.bin ./Objects/encrypted.bin关键参数说明参数说明示例值%L工程文件路径C:/Projects/STM32L工程名称MyProject.\工程所在目录-3.2 目录陷阱解决方案针对工程与脚本路径不一致问题提供三种可靠方案方案一绝对路径传递python D:\scripts\aes_encryptor.py ^ %D\Objects\%L.bin ^ %D\Objects\%L_enc.bin方案二环境变量法设置系统变量PY_SCRIPT_DIRKeil命令改为python %PY_SCRIPT_DIR%\aes_encryptor.py ...方案三批处理封装创建run_encrypt.batecho off pushd %~dp0 python aes_encryptor.py %* popdKeil中调用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( filenameencryption.log, levellogging.DEBUG, format%(asctime)s - %(levelname)s - %(message)s ) try: encrypt_file(input_file, output_file) except Exception as e: logging.error(f加密失败: {str(e)}) raise5. 进阶优化技巧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%以上的路径相关问题。当工程结构复杂时建议在脚本初始处打印当前工作目录和参数解析结果这对调试有极大帮助。

更多文章