C++使用openssl对AES-256-ECB PKCS7 加解密

文章介绍了AES-256-ECBPKCS7加密和解密算法的实现,包括加密函数AesEcb256Pkcs7Encrypt,解密函数AesEcb256Pkcs7Decrypt,以及PKCS7填充和去填充的辅助函数,通过示例展示了整个过程。
摘要由CSDN通过智能技术生成

/*
 * AES-256-ECB PKCS7 加密 函数
 * input:经过PKCS7填充后的明文数据
 * outhex:加密后的命名数据16进制数,可以使用base64_encode转换为base64格式字符串密文
 * key:密钥
 * len:经过PKCS7填充后的明文数据长度
 */
void AesEcb256Pkcs7Encrypt(u8 *input, u8 *outhex, u8 *key, int len)
{
	/* key:171ce897ad494cb289b023cd3c0ceab4 
	 * input:{terminalNumber}
	 * aesHexStr:6241579fb24b00f9d1d238ed191e700877b27ba4e7f6184253eb40c20f67390f
	 * base64str:YkFXn7JLAPnR0jjtGR5wCHeye6Tn9hhCU+tAwg9nOQ8=
	 *
	 * input:{"terminalNumber":"28b7f2eb-b549-3200-9950-2c6a83cd8af2"}
	 * aesHexStr:3B2EFE3D4BF2E586F06D9AC26B2F35CE67B2B228C5DE89980DE8CE3570EBBEE62EB54526A24542885D8902E860D54D056C6545D183B0A0134A48449C3D9F7B19
	 * base64str:Oy7+PUvy5YbwbZrCay81zmeysijF3omYDejONXDrvuYutUUmokVCiF2JAuhg1U0FbGVF0YOwoBNKSEScPZ97GQ==
	 */

	TRACE("input:%s, key:%s, %d\n", (char*)input, (char*)key, len);

    AES_KEY aesKey;
    AES_set_encrypt_key(key, 256, &aesKey);


	for (size_t i = 0; i < len; i += AES_BLOCK_SIZE)
	{
	    AES_encrypt(input + i, outhex + i, &aesKey);
		TRACE("i:%d\n\n", i);
	}

	/* 将加密后的数据转换成十六进制字符串 */
	std::string aesHexStr;
	for (size_t i = 0; i < len; ++i)
	{
	    char hex[3];
	    sprintf(hex, "%02X", outhex[i]);
	    aesHexStr += hex;
	}

	/* 将hex转为base64 */
	char base64str[2*len] = {0};
	base64_encode(outhex, base64str, len);

	TRACE("buf[%s], len:%d, hexAes[%s], len:%d\n", base64str, strlen(base64str), aesHexStr.data(), aesHexStr.length());
}

/*
 * AES-256-ECB PKCS7 解密 函数
 */
void AesEcb256Pkcs7Decrypt(unsigned char* input, unsigned char* output, unsigned char* key, int len)
{
    AES_KEY aesKey;
    AES_set_decrypt_key(key, 256, &aesKey);

    for (size_t i = 0; i < len; i += AES_BLOCK_SIZE)
	{
	    AES_decrypt(input + i, output + i, &aesKey);
		TRACE("i:%d\n\n", i);
	}

	/* 将加密后的数据转换成十六进制字符串 */
	std::string aesHexStr;
	for (size_t i = 0; i < len; ++i)
	{
	    char hex[3];
	    sprintf(hex, "%02X", output[i]);
	    aesHexStr += hex;
		TRACE("output[%d]:%s [%d]\n", i, hex, output[i]);
	}
}

// PKCS7填充函数
int Pkcs7Padding(char *data, int len)
{
    int padding_len = AES_BLOCK_SIZE - (len % AES_BLOCK_SIZE);
	TRACE("data:%s, len:%d, padding_len:%d \n\n", data, len, padding_len);
    for (int i = 0; i < padding_len; i++)
    {
        data[len + i] = (char)padding_len;
    }
	return len + padding_len;
}

//去除PKCS7填充
int Pkcs7Unpadding(unsigned char *data, int length) 
{
	/* 取出最后一个字节数据 */
	int padding_size = data[length - 1];

	TRACE("padding_size:%d ,%d ,%d\n\n", padding_size, data[length - 1], length);

	if (padding_size > AES_BLOCK_SIZE || padding_size == 0) 
	{
		TRACE("padding err\n\n");
		return -1; // 非法填充
	}

	int padding_index = length - padding_size;
	for (int i = 0; i < padding_size; i++)
	{
		if (data[padding_index+i] != (unsigned char)padding_size)
		{
			TRACE("padding err :%d ,%d\n\n", data[padding_index+i], padding_size);
			return -1; // 非法填充
		}
	}
	return padding_index;
}
int maintest()
{
	/* 256位密钥 */
    u8 *key = "171ce897ad494cb289b023cd3c0ceab4";
    char plaintext[256] = {0};
	/* 加密密文hex */
    unsigned char ciphertext[1024];
	
    unsigned char output[1024]; // 解密输出

	//sprintf(plaintext, "terminalNumber");
	//sprintf(plaintext, "{terminalNumber}");
	sprintf(plaintext, "{\"terminalNumber\":\"28b7f2eb-b549-3200-9950-2c6a83cd8af2\"}");

    /* PKCS7填充明文 */
    int allLen = Pkcs7Padding((char *)plaintext, strlen(plaintext));

	/* 加密 */
    AesEcb256Pkcs7Encrypt(plaintext, ciphertext, key, allLen);
	TRACE("plaintext:%s, len:%d key:%s \n\n", plaintext, allLen, key);

    /* 解密 */
    AesEcb256Pkcs7Decrypt(ciphertext, output, key, allLen);
	/* PKCS7解填充 */
    int plaintext_len = Pkcs7Unpadding(output, allLen); 

    if (plaintext_len == -1)
    {
        TRACE("AES Decrypt err\n");
    }
    else
    {
		TRACE("output:%s [%d]\n\n", output, plaintext_len);
    }

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值