在实际的物联网项目开发中,经常需要将设备采集到的数据远程传输到服务器端,设备也会接收远程服务器端下发过来的数据,这便是数据交互。如果这些数据只是通过明文方式 进行交互,那么是不安全的,那么就需要将数据进行加密和解密了。本文讲基于mbedtls的AES加解密在STM32上的使用,实现数据的加密和解密,举例ECB和CBC两种方式。
在这里我们使用常用的STM32开发工具Keil uVision5(MDK5),通过往Keil uVision5安装mbedTLS pack来实现移植。
1、下载mbedTLS pack
(1)到keil官网下载:http://www.keil.com/dd2/pack/
(2)找到ARM mbed Cryptographic and SSL/TLS library for Cortex-M devices,然后点击下载。
2、安装mbedTLS pack
(1)、将下载好的mbedTLS pack双击安装,目前最新是ARM.mbedTLS.1.5.0.pack,安装路径和安装keil5时的路径要对应,我是默认路径:
(2)用keil5打开任意一个stm32工程,按如下步骤操作,如果如下图,则表示安装成功:
3、移植mbedtls到STM32
(1)按如下步骤操作,完成之后,在左边窗口可以看到mbedtls相关文件:
(2)修改mbedTLS_config.h文件:
根据自己的需要修改mbedTLS_config.h文件,例如我这里需要用到AES,那么就需要打开相关的宏,对于AES的ECB和CBC加解密,如下打开这几个宏:
#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_C
1、ECB应用示例
ECB模式只能实现16字节的明文加解密。
(1)实现代码:
void mbedtls_aes_test(void)
{
mbedtls_aes_context aes_ctx;
//密钥数值
unsigned char key[16] = {'e', 'c', 'b', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd', '1', '2', '3', '4'};
//明文空间
unsigned char plain[16] = "hello_worled123";
//解密后明文的空间
unsigned char dec_plain[16]={0};
//密文空间
unsigned char cipher[16]={0};
mbedtls_aes_init( &aes_ctx );
//设置加密密钥
mbedtls_aes_setkey_enc( &aes_ctx, key, 128);
printf("plain:%s\r\n", plain);
mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, plain, cipher);
printf("cipher:%s\r\n", cipher);
//设置解密密钥
mbedtls_aes_setkey_dec(&aes_ctx, key, 128);
mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_DECRYPT, cipher, dec_plain );
printf("dec_plain:%s\r\n", dec_plain);
printf("\r\n");
mbedtls_aes_free( &aes_ctx );
}
(2)实验效果:
2、CBC应用示例
CBC能实现大于16字节的明文加解密,前提是需要为16的整数倍。
(1)实现代码:
void mbedtls_aes_test(void)
{
int i;
mbedtls_aes_context aes_ctx;
//密钥数值
unsigned char key[16] = {'c', 'b', 'c', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd', '1', '2', '3', '4'};
//iv
unsigned char iv[16];
//明文空间
unsigned char plain[64] = "hello_worled1234567890abcdefghijklmnopqrstuvwxyz12389";
//解密后明文的空间
unsigned char dec_plain[64]={0};
//密文空间
unsigned char cipher[64]={0};
mbedtls_aes_init( &aes_ctx );
//设置加密密钥
printf("plain:%s\r\n", plain);
mbedtls_aes_setkey_enc( &aes_ctx, key, 128);
for(i = 0; i < 16; i++)
{
iv[i] = 0x01;
}
mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT, 64, iv, plain, cipher);
printf("cipher:%s\r\n", cipher);
//设置解密密钥
mbedtls_aes_setkey_dec(&aes_ctx, key, 128);
for(i = 0; i < 16; i++)
{
iv[i] = 0x01;
}
mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, 64, iv, cipher, dec_plain);
printf("dec_plain:%s\r\n", dec_plain);
printf("\r\n");
mbedtls_aes_free( &aes_ctx );
}
(2)实验效果: