使用AES加密-复用前人的智慧

使用AES加密-复用前人的智慧

一. 头文件如下所示:
uint32_t encrypt_get_size(uint32_t size);

int32_t encrypt(uint8_t* data,
                uint32_t data_size,
                uint8_t* enc_data,
                uint32_t* enc_data_size);
 
int32_t decrypt(uint8_t* enc_data,
                uint32_t enc_data_size,
                uint8_t** data,
                uint32_t* data_size);
二. 加密代码:

AES算法以16个字节对齐,如果不是16个字节,需要补齐,

在这里AES_BLOCK_SIZE就是16,在openssl/aes.h里面有定义

typedef struct
{
	 uint32_t data_size;
	 uint32_t key[AES_BLOCK_SIZE];
	 uint32_t iv[AES_BLOCK_SIZE];
	 uint8_t data[AES_BLOCK_SIZE];
}

uint32_t encrypt_get_size(uint32_t size)
{
	uint32_t block_num = 0;
	uint32_t en_data_size = 0;
	
	if ((size % AES_BLOCK_SIZE) != 0)
	{
		block_num = size / AES_BLOCK_SIZE + 1;
		en_data_size = block_num * AES_BLOCK_SIZE;
	}
	else
	{
		en_data_size = size; 
	}
}

int32_t encrypt(uint8_t* data,
                uint32_t data_size,
                uint8_t* enc_data,
                uint32_t* enc_data_size)
{
    AES_KEY key;
    int ret         = 0;
    uint32_t length = 0;
    uint32_t block_num = 0;
    enc_data_t* obj   = NULL;

    obj = (enc_data_t*) enc_data;

    obj->data_len = data_size;
    memcpy(obj->data, data, data_size);
    
    ret = AES_set_encrypt_key(obj->key, 128, &key);
    if (ret != 0)
    {
        printf("AES_set_encrypt_key failed %d \n", ret);
        return ret;
    }

    if ((data_size % AES_BLOCK_SIZE) != 0)
    {
        block_num = data_size / AES_BLOCK_SIZE + 1;
        length = block_num * AES_BLOCK_SIZE;
    }
    else
    {
    	length = data_size;
    }
    
    AES_cbc_encrypt(obj->data, obj->data, length, &key, obj->iv, AES_ENCRYPT);

    *enc_data_size = sizeof(enc_data_t) + length;

    return ret;
}

三. 解密代码:
int decrypt(uint8_t* enc_data,
                 uint32_t enc_data_size,
                 uint8_t** data,
                 uint32_t* data_size)
{
    AES_KEY key;
    int ret           = 0;
    enc_data_t* obj   = NULL;
    uint8_t* tmp_data = NULL;

    obj = (enc_data_t*) enc_data;
    const uint32_t total_size = obj->data_len + sizeof(enc_data_t);

    ret = AES_set_decrypt_key(obj->key, 128, &key);
    if (ret != 0)
    {
        printf("AES_set_encrypt_key failed %d \n", ret);
        return ret;
    }

    AES_cbc_encrypt(obj->data,
    				obj->data,
    				(enc_data_size - sizeof(enc_data_t)),
    				&key,
    				obj->iv,
    				AES_DECRYPT);

    tmp_data = (uint8_t*) malloc(obj->data_len);
    if (NULL == tmp_data)
    {
        printf("allocate failed \n");
        return -1;
    }
    memset(tmp_data, 0, obj->data_len);
    memcpy(tmp_data, obj->data, obj->data_len);

    if (NULL == *data)
    {
        *data = tmp_data;
    }
    *data_size = obj->data_len;
    return 0;
}

四.代码的智慧分析:

在这里有一个问题,如果加密解密在不同的场景,就是说需要把加密数据保存成一个文件,
然后,从这个秘文文件中,把数据解密出来;但是这里存在的问题就是,你需要知道加密前
数据的大小,有人说,这个可以保存在一个全局的变量里面;但是会有这样的场景,你可能在
开机的时候就需要加载这个密文的数据取解密,这个时候怎么办呢?一般人的结局方法如下:
保存加密数据的时候,以数组追加的形式保存两段数据,第一段数据是用一个固定长度的数据(4个字节),来存储原始数据的长度,第二段数据就是加密的秘文数据;载读取解析加密数据的时候也是这样分为两个步骤,第一步是读取一个固定长度(4个字节)的数据,就是原始数据的大小,即解密后数据的大小,第二步,就是读取保存的秘文。这种方法也是可行的,就是比较麻烦。其实好的方案就是采用上面的方法,内部定义一段数据结构,通过解析固定的数据结构来做

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想全栈程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值