STM32F103CBT6实战:mbedtls v2.24.0的SHA1加密从零实现
在物联网设备开发中,数据安全传输是基础要求。SHA1作为经典哈希算法,虽然已不推荐用于高安全场景,但在资源受限的STM32F103CBT6这类Cortex-M3内核MCU上,仍是验证加密库移植的理想起点。本文将手把手带你在72MHz主频的STM32F103上,用mbedtls v2.24.0实现字符串SHA1加密,并通过串口输出验证结果。
1. 环境准备与工程创建
1.1 硬件与工具链配置
所需物料清单:
- STM32F103CBT6最小系统板(64KB Flash/20KB RAM)
- ST-Link V2调试器
- USB-TTL串口模块(用于输出调试信息)
开发环境配置步骤:
- 安装Keil MDK 5.29(需包含STM32F1xx Device Family Pack)
- 下载STM32CubeMX 6.0.1
- 获取mbedtls 2.24.0源码包( 官方GitHub发布页 )
# 示例:Linux下获取源码 wget https://github.com/ARMmbed/mbedtls/archive/refs/tags/v2.24.0.tar.gz tar -xzvf v2.24.0.tar.gz1.2 CubeMX基础工程生成
- 新建Project选择STM32F103CBTx型号
- 配置时钟树:
- HSE 8MHz → PLLCLK 72MHz
- SYSCLK 72MHz
- APB1 Prescaler /2 (36MHz)
- 启用USART1:
- 波特率115200
- 8数据位/无校验
- 生成MDK-ARM工程时勾选"Copy only necessary library files"
注意:务必在Project Manager选项卡中勾选"Generate peripheral initialization as a pair of .c/.h files"以保持代码整洁。
2. mbedtls库裁剪与移植
2.1 源码目录结构整合
将下载的mbedtls-2.24.0解压后,按以下结构组织工程文件:
Your_Project/ ├── Core/ ├── Drivers/ ├── mbedtls/ │ ├── include/ # 头文件 │ └── library/ # 源文件 └── MDK-ARM/关键操作:
// 在main.h中添加全局宏定义 #define MBEDTLS_CONFIG_FILE "<mbedtls/config-mini-tls1_1.h>"2.2 配置文件优化
修改config-mini-tls1_1.h实现最小功能集:
/* System support */ #define MBEDTLS_HAVE_ASM //#define MBEDTLS_HAVE_TIME // 注释掉时间相关功能 /* mbed TLS modules */ #define MBEDTLS_SHA1_C // 启用SHA1模块 #define MBEDTLS_MD_C #define MBEDTLS_NO_PLATFORM_ENTROPY // 关键:禁用平台熵源需要添加到Keil工程的源文件清单:
mbedtls/library/sha1.cmbedtls/library/md.cmbedtls/library/platform.c
3. SHA1功能实现与验证
3.1 串口重定向配置
在main.c中添加标准IO重定向:
/* USER CODE BEGIN 4 */ #include <stdio.h> #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } /* USER CODE END 4 */3.2 SHA1加密核心代码
在main.c中实现测试函数:
void sha1_demo(const char *input) { uint8_t output[20]; // SHA1结果固定20字节 mbedtls_sha1_context ctx; printf("\r\nOriginal: %s\r\n", input); // 四步完成哈希计算 mbedtls_sha1_init(&ctx); mbedtls_sha1_starts(&ctx); mbedtls_sha1_update(&ctx, (const uint8_t *)input, strlen(input)); mbedtls_sha1_finish(&ctx, output); mbedtls_sha1_free(&ctx); // 打印十六进制结果 printf("SHA1: "); for(int i=0; i<20; i++) { printf("%02x", output[i]); } printf("\r\n"); }调用示例:
/* USER CODE BEGIN 2 */ sha1_demo("Hello,mbedtls!"); sha1_demo("STM32F103CBT6"); /* USER CODE END 2 */4. 编译调试与结果验证
4.1 常见编译问题解决
可能遇到的错误及解决方案:
| 错误类型 | 解决方法 |
|---|---|
| 未定义MBEDTLS_CONFIG_FILE | 在工程选项→C/C++→Define中添加宏 |
| 缺少platform_entropy_poll | 启用MBEDTLS_NO_PLATFORM_ENTROPY |
| 栈溢出 | 修改startup_stm32f103xb.s中Stack_Size EQU 0x400 |
4.2 运行结果比对
使用在线工具验证输出:
- 访问 1024Tools Hash计算
- 输入相同字符串,选择SHA1算法
- 对比设备串口输出与网页结果
示例输出:
Original: champion666 SHA1: a3f5c7d8e1b9f2d4c6a8b0e5d3f7c9a1b2d4e64.3 性能优化建议
通过以下配置提升运行效率:
// 在stm32f1xx_hal_conf.h中启用硬件CRC #define HAL_CRC_MODULE_ENABLED // 修改mbedtls配置 #define MBEDTLS_SHA1_ALT // 启用硬件加速(需实现对应HAL函数)工程完整内存占用报告:
- Program Size: Code=18256 RO-data=672 RW-data=48 ZI-data=2048
- 约占Flash 28%,RAM 10%