RSA加密测试,基于esp_encrypted_img组件
- 1. 开发环境
- 2. 简单描述
- 3. 公钥私钥生成代码(python)
- 3. 使用密钥(公钥私钥)对文件进行加密
- 4. ESP32 解密程序
1. 开发环境
- 开发环境为 IDF5.3.1
- 采用乐鑫官方组件库
- 组件库地址 :
https://components.espressif.com/components/espressif/esp_encrypted_img/versions/2.2.1
2. 简单描述
加密 | 解密 | 结果 |
---|---|---|
公钥 | 私钥 | 成功 |
私钥 | 私钥 | 成功 |
公钥 | 公钥 | 失败 |
私钥 | 公钥 | 失败 |
- 结论只有私钥可以解密!(不知为啥)
3. 公钥私钥生成代码(python)
from Crypto import Random
from Crypto.PublicKey import RSA# 伪随机数生成器
random_gen = Random.new().read# 生成秘钥对实例对象:2048是秘钥的长度
rsa = RSA.generate(3072, random_gen)# 获取私钥,保存到文件
private_pem = rsa.exportKey()
with open('private.pem', 'wb') as f:f.write(private_pem)# 获取公钥保存到文件
public_pem = rsa.publickey().exportKey()
with open('public.pem', 'wb') as f:f.write(public_pem)
3. 使用密钥(公钥私钥)对文件进行加密
-
esp_enc_img_gen.py 【esp_encrypted_img里面的脚本】
-
加密命令
python esp_enc_img_gen.py encrypt /path/to/input.bin /path/to/RSA-public-key /path/to/enc.bin
- 解密命令
python esp_enc_img_gen.py decrypt /path/to/enc.bin /path/to/RSA-private-key /path/to/output.bin
4. ESP32 解密程序
- CMAKE 导入密钥和需要解密的文件
idf_build_get_property(project_dir PROJECT_DIR)idf_component_register(SRCS "hello_world_main.c"INCLUDE_DIRS ""EMBED_TXTFILES ${project_dir}/rsa_key/public.pemEMBED_FILES ${project_dir}/rsa_key/image.bin)create_esp_enc_img(${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.bin${project_dir}/rsa_key/public.pem ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}_secure.bin app)target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-unused-const-variable)
- 解密代码
/** SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD** SPDX-License-Identifier: Apache-2.0*/#include <string.h>#include "freertos/FreeRTOS.h"
#include "freertos/ringbuf.h"#include "esp_log.h"
#include "esp_ota_ops.h"
#include "nvs_flash.h"
#include "esp_bt.h"
#include "ble_ota.h"#define OTA_RINGBUF_SIZE 8192
#define OTA_TASK_SIZE 8192static const char *TAG = "ESP_BLE_OTA";#if CONFIG_EXAMPLE_USE_PRE_ENC_OTA// 公钥
extern const char rsa_private_pem_start[] asm("_binary_public_pem_start");
extern const char rsa_private_pem_end[] asm("_binary_public_pem_end");// 文件
extern const uint8_t bin_start[] asm("_binary_image_bin_start");
extern const uint8_t bin_end[] asm("_binary_image_bin_end");esp_decrypt_handle_t decrypt_handle;
#endifvoid app_main(void)
{// 私钥解密esp_decrypt_cfg_t cfg = {};cfg.rsa_priv_key = rsa_private_pem_start;cfg.rsa_priv_key_len = rsa_private_pem_end - rsa_private_pem_start;decrypt_handle = esp_encrypted_img_decrypt_start(&cfg);if (!decrypt_handle){ESP_LOGE(TAG, "OTA upgrade failed");}pre_enc_decrypt_arg_t *args = calloc(1, sizeof(pre_enc_decrypt_arg_t));args->data_in = (char *)bin_start;args->data_in_len = bin_end - bin_start;esp_err_t err;err = esp_encrypted_img_decrypt_data(decrypt_handle, args);ESP_ERROR_CHECK(err);printf("Successful \n");printf("Successful = %s\n", args->data_out);printf("Successful = %d\n", args->data_out_len);printf("Successful = %.*s\n", args->data_out_len, args->data_out);printf("\n");err = esp_encrypted_img_decrypt_end(decrypt_handle);ESP_ERROR_CHECK(err);if (args->data_out){free(args->data_out);}free(args);
}