本帖最后由 damiaa 于 2024-8-16 08:46 编辑
【NUCLEO H533RE】之七 跑AES加解密算法
加解密算法在通信领域是经常需要用到的安全算法。AES算法是目前流行和可以使用的安全通信算法。
属于对称加密算法。优点就是数据加解密快,可以比较多的数据的加解密。缺点就是双方必须有同样的密钥,而且通信前必须要知道。
还有一种非对称加密算法,可以双方经过交换数据获得同样的加密密码。这样就通信前不需要知道密钥。缺点就是加解密慢。
现在很多就是用非对称加密算法+对称加密算法结合起来进行密钥交换和通信:
非对称加密算法获取密钥,双方都知道同样密钥后用对称加密算法(比如AES)进行比较大的加解密数据和通信。
非对称加密算法这里不讨论。
这里就用H533RE跑一下这个算法。AES里面最基本的是ECB 其次就是CBC,当然还有几种。这里就不一一演示。
AES算法如下图有几种:ECB、CBC、CTR、OFB、CFB 每一种有一些不同,具体大家可以去查查资料。
先说一下ECB,ECB只有key(发送和接收双方都有用一样样的key 16字节)。自己可以任意修改。
我们是靠这个key去保密。不能给人知道。
如果是CBC,还有16字节得初始值IV就像下面这样,也是可以任意修改。
每种AES都有模式,主要是为了规定如何填充不够16字节的部分。如果选择None模式,那自己给16字节数据的倍数的数据去加密。
PKCS7就是不够的填数字,这个数据就是少多少字节填多少的数字,比如少3个,就填03 03 03.
另外如果是刚好是16字节,那得多填16字节得10 10 10…大概就这个意思
PKCS7的好处就是可以想发几个字节发几个,不用纠结一定要是16字节的倍数,这样灵活方便,但也要处理一下;
这里模式好像stm32库没搞,可以自己代码实现,如何实现这里先不讨论。
另外base64和hex的转换这里也没有,也可以自己代码实现,所以今天不讨论这个,直接用hex转hex
下面开始实验ECB 生成一个H533得项目,也可以用原来的,然后选择AES
保存,然后就生成了一个项目。修改一下代码
Key还是让他为0000…
编译运行,比较结果正确:
下面再来演示一下cbc
我们修改模式为cbc,这次密码改一下,改为16进制的 00112233445566778899aabbccddeeff,iv有了,也改为 00112233445566778899aabbccddeeff
当然,我们可以这里改,程序中也可以随便修改。
保存文件,程序变成如下:
编译运行查看结果,比较如下:
主要代码如下:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @File : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
CRYP_HandleTypeDef hcryp;
uint32_t pKeyAES[4] = {0x00112233,0x44556677,0x8899AABB,0xCCDDEEFF};
uint32_t pInitVectAES[4] = {0x00112233,0x44556677,0x8899AABB,0xCCDDEEFF};
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_AES_Init(void);
static void MX_ICACHE_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t Uartrec2RBuf[2];
//串口回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2)
{
//WriteOneComX(&Uartrec2,Uartrec2.RBuf[0]);
HAL_UART_Receive_IT(huart,Uartrec2RBuf,1);
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_AES_Init();
MX_ICACHE_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart2,(uint8_t *)Uartrec2RBuf,1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
uint32_t in[128] ={0x11111111,0x22222222,0x33333333,0x44444444,0x55555555,0x66666666,0x77777777,0x88888888,0x0};
uint32_t EncryptedTxt[128]={0};
uint8_t EncryptedTxtPrint[256]={0};
uint32_t DecryptedTxt[128]={0};
uint8_t DecryptedTxtPrint[256]={0};
#define encry_len 32
if (HAL_CRYP_Encrypt(&hcryp, (uint32_t *)in, encry_len, EncryptedTxt, 1000) != HAL_OK)
{
/* Processing Error */
Error_Handler();
}
for(int i=0;i<encry_len/4;i++){
sprintf(EncryptedTxtPrint+9*i," %08X",EncryptedTxt[i]);
}
HAL_UART_Transmit_IT(&huart2,(const uint8_t*)&EncryptedTxtPrint[0], encry_len+4);
HAL_Delay(1000);
if (HAL_CRYP_Decrypt(&hcryp,EncryptedTxt , encry_len, DecryptedTxt, 1000) != HAL_OK)
{
/* Processing Error */
Error_Handler();
}
for(int i=0;i<encry_len/4;i++){
sprintf(DecryptedTxtPrint+9*i," %08X,",DecryptedTxt[i]);
}
HAL_UART_Transmit_IT(&huart2,(const uint8_t*)&DecryptedTxtPrint[0], encry_len+4);
HAL_Delay(1000);
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
HAL_Delay(10000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_PCLK3;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
/** Configure the programming delay
*/
__HAL_FLASH_SET_PROGRAM_DELAY(FLASH_PROGRAMMING_DELAY_0);
}
/**
* @brief AES Initialization Function
* @param None
* @retval None
*/
static void MX_AES_Init(void)
{
/* USER CODE BEGIN AES_Init 0 */
/* USER CODE END AES_Init 0 */
/* USER CODE BEGIN AES_Init 1 */
/* USER CODE END AES_Init 1 */
hcryp.Instance = AES;
hcryp.Init.DataType = CRYP_NO_SWAP;
hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
hcryp.Init.pKey = (uint32_t *)pKeyAES;
hcryp.Init.pInitVect = (uint32_t *)pInitVectAES;
hcryp.Init.Algorithm = CRYP_AES_CBC;
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
hcryp.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
hcryp.Init.KeyMode = CRYP_KEYMODE_NORMAL;
if (HAL_CRYP_Init(&hcryp) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN AES_Init 2 */
/* USER CODE END AES_Init 2 */
}
/**
* @brief ICACHE Initialization Function
* @param None
* @retval None
*/
static void MX_ICACHE_Init(void)
{
/* USER CODE BEGIN ICACHE_Init 0 */
/* USER CODE END ICACHE_Init 0 */
/* USER CODE BEGIN ICACHE_Init 1 */
/* USER CODE END ICACHE_Init 1 */
/** Enable instruction cache (default 2-ways set associative cache)
*/
if (HAL_ICACHE_Enable() != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ICACHE_Init 2 */
/* USER CODE END ICACHE_Init 2 */
}
/**
* @brief USART2 Initialization Function
* @param None
* @retval None
*/
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT|UART_ADVFEATURE_DMADISABLEONERROR_INIT;
huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
huart2.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PA5 */
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PC4 */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
好,实验先到这里。感谢大家!