openssl的aes头文件
#include
简介:openssl标准库将加解密函数统一封装成AES_ecb_encrypt函数,通过第四个参数来选择调用加密程序或者解密程序,需要注意的是第三个参数需要通过AES_set_decrypt_key、AES_set_encrypt_key来生成。ECB模式相较于CBC模式少一个输入参数iv向量,整体调用大同小异。
参数名称 | 释义 |
---|---|
in | 加解密接口输入 |
out | 加解密接口输出 |
key | AES_KEY类型密钥需要通过接口生成(后面有介绍) |
enc | 常量AES_ENCRYPT表示用于加密、AES_DECRYPT表示用于解密 |
void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, const int enc)
{
assert(in && out && key);
assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
if (AES_ENCRYPT == enc)
AES_encrypt(in, out, key);
else
AES_decrypt(in, out, key);
}
简介:用于生成AES_ecb_encrypt加解密所需要的KEY,注意加解密的密钥使用对应函数生成。
int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
参数名称 | 释义 |
---|---|
userKey | 输入密钥 |
bits | 密钥长度的比特位数即字节数*8,128,192,256三个参数可供选择 |
key | AES_KEY类型输出密钥用于AES_ecb_encrypt加密 |
返回值 | 0:表示成功,-1:输入参数1为空,-2:bit位输入错误 |
说明:运用标准库的加密函数和密钥生成函数就可以加密解密了,但是对于上述加解密接口一次之只能处理16个字节长度的数据,如果需要加密的明文小于等于十六个字节,则可以直接使用上述的加解密接口,当明文长度大于16个字节时则需要将明文分组加密再将密文拼接起来。所以对于输入数据的字节长度要求为16的整倍数,当分组后不足16字节的一组用0x00填充,即为zeros padding,这里介绍zeros padding的填充方式,其他填充方式网上介绍很多这里就不赘述。
int AES_ECB128_Encrypt(const unsigned char *in, unsigned char *out, unsigned char key, int input_len) {
AES_KEY key;
int i;
int ret = 0;
int round = 0;
int rest = 0;
int in_len = 0;
unsigned char in_tmp[1024] = {0};
unsigned char out_tmp[1024] = {0};
unsigned char zero[16] = {0};
//DEBUG_INFO() 是自定义打印接口函数,使用中可以修改为对应的打印函数
ret = AES_set_encrypt_key(key, 128, &key);
if ( ret < 0) {
DEBUG_INFO("ret = %d,%s\n", ret, "get the Encrypt aes key error");
return false;
} else {
DEBUG_INFO("%s\n", "get the Encrypt key successful");
}
in_len = input_len;
memset(zero, 0x00, 16);
if (in_len <= 16) {
AES_ecb_encrypt(in, out, &key, AES_ENCRYPT);
} else{
rest = in_len%16;
round = (in_len - rest)/16;
memcpy(in_tmp, in, 1024);
strcat(in_tmp, zero);
memcpy(in, in_tmp, (round+1) * 16); //zero padding
for (i = 0; i < round + 1; i++) { //分组循环加密并且拼接
memcpy(in_tmp, in + 16 * i, 16);
AES_ecb_encrypt(in_tmp, out_tmp, &key, AES_ENCRYPT);
memcpy(out + 16 * i, out_tmp, 16);
memset(in_tmp, 0, 1024);
memset(out_tmp, 0, 1024);
}
}
return true;
}
参数名称 | 释义 |
---|---|
in | 加密接口输入 |
out | 加密接口输出 |
key | 输入密钥key |
input_len | 输入明文数据长度 |
int AES_ECB128_Decrypt(const unsigned char *in, unsigned char *out, unsigned char key,int input_len) {
AES_KEY key;
int i;
int j;
int cnt;
int ret = 0;
int rest = 0;
int round = 0;
int in_len = 0;
int out_len=0;
unsigned char in_tmp[1024] = {0};
unsigned char out_tmp[1024] = {0};
ret = AES_set_decrypt_key(dct_conf.servers[server_index].mqtt_conf.aes_key, 128, &key);
if ( ret < 0) {
DEBUG_INFO("ret = %d,%s\n", ret, "get the Decrypt aes key error");
return false;
} else {
DEBUG_INFO("%s\n", "get the Decrypt key successful");
}
in_len = input_len;
if (in_len == 16) {
AES_ecb_encrypt(in, out, &key, AES_DECRYPT);
} else {
round = in_len/16;
for (i = 0; i < round; i++) { //分组解密
if (i == round -1) {
memcpy(in_tmp, in + 16 * i, 16);
AES_ecb_encrypt(in_tmp, out_tmp, &key, AES_DECRYPT);
for (j = 0; j < 16; j++) { //去掉填充在末尾的零(事实上这边的算法需要改进可以评论出你的想法噢哈哈哈)
if (out_tmp[j] == '\0') {
ret = 16 - j;
break;
}
}
memcpy(out + 16 * i, out_tmp, 16);
} else {
memcpy(in_tmp, in + 16 * i, 16);
AES_ecb_encrypt(in_tmp, out_tmp, &key, AES_DECRYPT);
memcpy(out + 16 * i, out_tmp, 16);
memset(in_tmp, 0, 1024);
memset(out_tmp, 0, 1024);
}
}
}
参数名称 | 释义 |
---|---|
in | 加密接口输入 |
out | 加密接口输出 |
key | 输入密钥key |
input_len | 输入明文数据长度 |