ESP32学习笔记(47)——加密算法AESMD5SHA ⼀、简介
1.1 SSL
SSL:(Secure Socket Layer,安全套接字层),位于可靠的⾯向连接的⽹络层协议和应⽤层协议之间的⼀种协议层。SSL通过互相认证、使⽤数字签名确保完整性、使⽤加密确保私密性,以实现客户端和服务器之间的安全通讯。该协议由两层组成:SSL记录协议和SSL握⼿协议。 1.2 TLS
TLS:(Transport Layer Security,传输层安全协议),⽤于两个应⽤程序之间提供保密性和数据完整性。该协议由两层组成:TLS记录协议和TLS握⼿协议。 1.3 mbed TLS
乐鑫esp-idf框架集成开源的 mbedtls 加密库。mbedtls 也许是最⼩巧的SSL代码库。⾼效、便于移植和集成。⽀持常见的安全算法,如:AES、DES、RSA、ECC、SHA256、MD5、BASE64等等。除此之外还⽀持公钥证书体系。它提供了具有直观的 API 和可读源代码的SSL 库。该⼯具即开即⽤,可以在⼤部分系统上直接构建它,也可以⼿动选择和配置各项功能。 从功能⾓度来看,该mbedtls分为三个主要部分:
SSL/TLS 协议实施。
⼀个加密库。
⼀个 X.509 证书处理库。
⼆、AES - ECB
2.1 简介
AES(Advanced Encryption Standard,⾼级加密标准) ⼜称Rijndael加密法,是美国联邦政府采⽤的⼀种区块加密标准。
ECB(Electronic Code Book电⼦密码本),是最早采⽤和最简单的模式,它将加密的数据分成若⼲组,每组的⼤⼩跟加密密钥长度相同,然后每组都⽤相同的密钥进⾏加密。 优点:
简单;
有利于并⾏计算;
误差不会被传送;
缺点:
不能隐藏明⽂的模式;
可能对明⽂进⾏主动攻击;
因此,此模式适于加密⼩消息。
2.2 API说明
API ⽂档查看
2.2.1 mbedtls_aes_init
功能初始化指定的 AES 上下⽂。它必须是在使⽤上下⽂之前调⽤的第⼀个 API。
函数定义void mbedtls_aes_init(mbedtls_aes_context * ctx)
参数ctx:要初始化的 AES 上下⽂。这⼀定不是NULL。
返回⽆
2.2.2 mbedtls_aes_setkey_enc
功能设置加密密钥。
函数定义int mbedtls_aes_setkey_enc(mbedtls_aes_context * ctx, const unsigned char * key, unsigned int keybits)
参数
ctx:密钥应绑定到的 AES 上下⽂。它必须被初始化。
key:加密密钥。这必须是⼤⼩keybits位的可读缓冲区。
keybits:以位为单位传递的数据⼤⼩。有效的选项是:128 位 / 192位 / 256 位
返回0 - 成功,0x0020 - 密钥长度⽆效2.2.3 mbedtls_aes_crypt_ecb
功能
执⾏ AES 单块加密或解密操作。
它对mode参数中定义的输⼊数据缓冲区执⾏参数中定义的操作(加密或解密)input。
mbedtls_aes_init()以及mbedtls_aes_setkey_enc()或mbedtls_aes_setkey_dec()必须在第⼀次使⽤相同上下⽂调⽤此 API 之前调
⽤。
函数定
义
int mbedtls_aes_crypt_ecb(mbedtls_aes_context * ctx, int mode, const unsigned char input[16], unsigned char output[16])
参数
ctx:⽤于加密或解密的 AES 上下⽂。它必须被初始化并绑定到⼀个键。mode:AES 操作:MBEDTLS_AES_ENCRYPT或MBEDTLS_AES_DECRYPT。
input:保存输⼊数据的缓冲区。它必须是可读的,并且16长度⾄少为Bytes。output:将写⼊输出数据的缓冲区。它必须是可写的,并且16长度⾄少为Bytes。
返回0 - 成功
2.2.4 mbedtls_aes_setkey_dec
功能设置解密密钥。
函数定义int mbedtls_aes_setkey_dec(mbedtls_aes_context * ctx, const unsigned char * key, unsigned int keybits)
参数
ctx:密钥应绑定到的 AES 上下⽂。它必须被初始化。
key:解密密钥。这必须是⼤⼩keybits位的可读缓冲区。
keybits:以位为单位传递的数据⼤⼩。有效的选项是:128 位 / 192位 / 256 位
返回0 - 成功,0x0020 - 密钥长度⽆效2.2.5 mbedtls_aes_free
功能释放并清除指定的 AES 上下⽂。
函数定义void mbedtls_aes_free(mbedtls_aes_context * ctx)
参数ctx:要清除的 AES 上下⽂。如果是NULL,则此函数不执⾏任何操作。否则,上下⽂必须⾄少已初始化。
返回⽆
2.3 实例
ECB模式只能实现16字节的明⽂加解密。
需要包含 mbedtls/aes.h
#include<stdio.h>
#include"sdkconfig.h"
#include"freertos/FreeRTOS.h"
#include"freertos/task.h"
#include"esp_system.h"
#include"mbedtls/aes.h"
void app_main(void)
{
printf("AES-ECB 加密-数据块(128位),偏移量为0\n");
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]="test1234";
//解密后明⽂的空间
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("要加密的数据: %s\n", plain);
printf("加密的密码: %s\n", key);
mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, plain, cipher);
printf("加密结果,⼆进制表⽰: ");
for(int loop =0; loop <16; loop++)
{
printf("%02x", cipher[loop]);
}
printf("\r\n");
//设置解密密钥
mbedtls_aes_setkey_dec(&aes_ctx, key,128);
mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_DECRYPT, cipher, dec_plain);
printf("解密后的数据: %s\n", dec_plain);
mbedtls_aes_free(&aes_ctx);
}
2.4 加密解密验证
与⽹站加密后结果⼀致:
三、AES - CBC
3.1 简介
AES(Advanced Encryption Standard,⾼级加密标准) ⼜称Rijndael加密法,是美国联邦政府采⽤的⼀种区块加密标准。CBC(Cipher Block Chaining,加密块链) 模式。
优点:
不容易主动攻击,安全性好于ECB,适合传输长度长的报⽂,是SSL、IPSec的标准。
缺点:
不利于并⾏计算;
误差传递;
需要初始化向量IV;
3.2 API说明
API ⽂档查看
3.2.1 mbedtls_aes_init
功能初始化指定的 AES 上下⽂。它必须是在使⽤上下⽂之前调⽤的第⼀个 API。
函数定义void mbedtls_aes_init(mbedtls_aes_context * ctx)
参数ctx:要初始化的 AES 上下⽂。这⼀定不是NULL。
返回⽆
功能初始化指定的 AES 上下⽂。它必须是在使⽤上下⽂之前调⽤的第⼀个 API。
3.2.2 mbedtls_aes_setkey_enc
功能设置加密密钥。
函数定义int mbedtls_aes_setkey_enc(mbedtls_aes_context * ctx, const unsigned char * key, unsigned int keybits)
参数
ctx:密钥应绑定到的 AES 上下⽂。它必须被初始化。
key:加密密钥。这必须是⼤⼩keybits位的可读缓冲区。
keybits:以位为单位传递的数据⼤⼩。有效的选项是:128 位 / 192位 / 256 位
返回0 - 成功,0x0020 - 密钥长度⽆效3.2.3 mbedtls_aes_crypt_cbc
功能
执⾏ AES-CBC 加密或解密操作。
它对mode参数中定义的输⼊数据缓冲区执⾏参数中定义的操作(加密或解密)input。
mbedtls_aes_init()以及mbedtls_aes_setkey_enc()或mbedtls_aes_setkey_dec()必须在第⼀次使⽤相同上下⽂调⽤此 API 之前调⽤。
该函数对完整块进⾏操作,即输⼊⼤⼩必须是 AES 块⼤⼩的16Bytes的倍数。
函数定义int mbedtls_aes_crypt_cbc(mbedtls_aes_context * ctx, int mode, size_t length, unsigned char iv[16], const unsigned char * input,
unsigned char * output)
参数
ctx:⽤于加密或解密的 AES 上下⽂。它必须被初始化并绑定到⼀个键。mode:AES 操作:MBEDTLS_AES_ENCRYPT或MBEDTLS_AES_DECRYPT。length:输⼊数据的长度(以字节为单位)。这必须是块⼤⼩(16字节)的倍数。
iv:初始化向量(使⽤后更新)。它必须是⼀个可读可写的16字节缓冲区。
input:保存输⼊数据的缓冲区。它必须是可读的并且⼤⼩为length Bytes。
output:保存输出数据的缓冲区。它必须是可写的并且⼤⼩为length Bytes。
返回0 - 成功
3.2.4 mbedtls_aes_setkey_dec
功能设置解密密钥。
函数定义int mbedtls_aes_setkey_dec(mbedtls_aes_context * ctx, const unsigned char * key, unsigned int keybits)
参数
ctx:密钥应绑定到的 AES 上下⽂。它必须被初始化。
key:解密密钥。这必须是⼤⼩keybits位的可读缓冲区。
keybits:以位为单位传递的数据⼤⼩。有效的选项是:128 位 / 192位 / 256 位
返回0 - 成功,0x0020 - 密钥长度⽆效
3.2.5 mbedtls_aes_free
功能释放并清除指定的 AES 上下⽂。
函数定义void mbedtls_aes_free(mbedtls_aes_context * ctx)
参数ctx:要清除的 AES 上下⽂。如果是NULL,则此函数不执⾏任何操作。否则,上下⽂必须⾄少已初始化。
返回⽆
3.3 实例
CBC能实现⼤于16字节的明⽂加解密,前提是需要为16的整数倍。
需要包含 mbedtls/aes.h