openssl aes cbc256加密解密


#include "ads_cbc256.h"
#include <openssl/aes.h>
int base64_encode(char *_pInput, int _InLen, char *_pOutput, int *_pOutLen)
{
	BIO *bio = NULL;
	BIO *bio_mem = NULL;
	
    char *base64text;
    long base64textlen;
	int len = 0;

    if (_pInput == NULL || _pOutput == NULL || _pOutLen == NULL) {
        return -1;
    }
 
    bio = BIO_new(BIO_f_base64());
    bio_mem = BIO_new(BIO_s_mem());
    bio = BIO_push(bio, bio_mem);
 
    len = BIO_write(bio, _pInput, _InLen);
    BIO_flush(bio);
 
    BIO_get_mem_data(bio, &base64text);
    base64textlen = BIO_get_mem_data(bio, NULL);
 
    // 输出 base64 编码的密文
    printf("Base64 Encoded Ciphertext: %s\n", base64text);
 
    *_pOutLen = strlen(base64text);
    memcpy(_pOutput, base64text, *_pOutLen);
 
    // 清理资源
    BIO_free_all(bio);
 
    return 0;               /* SUCCESS */
}
 
/*
*****************************************************************************************
*	函 数 名: base64_encode
*	功能说明: 将Base64编码的字符串data转换回原始字符串
*	形    参:   _pInput :    输入数据
*               _InLen  :   输入数据长度
*               _pOutput:   输出base64编码结果
*               _OutLen:   输出数据长度
*	返 回 值: 0:成功, -1:失败
*****************************************************************************************
*/
int base64_decode(char *_pInput, int _InLen, char *_pOutput, int _OutLen)
{
    BIO *bmem, *b64;
    int outlen = 0;
 
    if (_pInput == NULL || _pOutput == NULL) {
        printf("param failed\n");
        return -1;
    }
 
    b64 = BIO_new(BIO_f_base64());              // 创建Base64解码的BIO
    if (b64 == NULL) {
        printf("BIO_f_base64 failed\n");
        return -1;
    }
 
    bmem = BIO_new_mem_buf(_pInput, _InLen);    // 创建内存BIO
    if (bmem == NULL) {
        printf("BIO_new_mem_buf failed\n");
        BIO_free_all(b64);
        return -1;
    }
 
    bmem = BIO_push(b64, bmem);                 // 将解码BIO链接到内存BIO
 
    outlen = BIO_read(bmem, _pOutput, _OutLen);    // 读取解码后的数据
    if (outlen < 0) {
        printf("BIO_read failed\n");
        BIO_free_all(b64);
        return -1;
    }
 
    // 输出解码后的数据
    printf("Decoded data: %s\n", _pOutput);
 
    BIO_free_all(bmem);             //释放
    return 0;
}
 
/*
*****************************************************************************************
*	函 数 名: aes_encrypt_string
*	功能说明: AES加密字符串
*	形    参:   _pPassword  :   密码
*               _pInput     :   输入数据
*               _InLen      :   输入数据长度
*               _pOutBuf    :   输出AES编码数据
*               _pOutLen    :   输出AES编码数据长度
*	返 回 值: 0:成功, -1:失败
*****************************************************************************************
*/
int aes_encrypt_string(/*char *_pPassword, */char *_pInput, int _InLen, char *_pOutBuf, int *_pOutLen, unsigned char key[], unsigned char iv[])
{
    EVP_CIPHER_CTX *pEn_ctx;
    int flen = 0, outlen = 0;
    int i, nrounds = 1;
	int remainder = 0;
    //unsigned char key[32], iv[32];
    const EVP_CIPHER *cipherType = EVP_aes_256_cbc();
 
    if (/*_pPassword == NULL ||*/ _pInput == NULL || _pOutBuf == NULL || _pOutLen == NULL) {
        return -1;
    }
	/*printf("in: %d\n", _InLen);
	for ( i = 0; i < _InLen; i++) {
        printf("[in] %02X ", _pInput[i] & 0xFF);
    }
	printf("\n");*/
    /*
    * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material.
    * nrounds is the number of times the we hash the material. More rounds are more secure but
    * slower.
    */
    /*i = EVP_BytesToKey(cipherType, EVP_md5(), NULL, _pPassword, strlen(_pPassword), nrounds, key, iv);  //输入密码产生了密钥key和初始化向量iv
    if (i != 32) {
        printf("Key size is %d bits - should be 256 bits\n", i);
        return -1;
    }*/
 
    pEn_ctx = EVP_CIPHER_CTX_new();                             //创建加密上下文
 
    EVP_CIPHER_CTX_init(pEn_ctx);                               //初始化 EVP_CIPHER_CTX 上下文
    EVP_EncryptInit_ex(pEn_ctx, cipherType, NULL, key, iv);     //初始化加密操作
 
    /* Update cipher text */
    if (!EVP_EncryptUpdate(pEn_ctx, (unsigned char*)_pOutBuf, &outlen,(unsigned char*)_pInput, _InLen)) {   //处理数据
        perror("\n Error,ENCRYPR_UPDATE:");
        return -1;
    }
 
#if 1
    /* updates the remaining bytes */
    if (!EVP_EncryptFinal_ex(pEn_ctx, (unsigned char*)(_pOutBuf + outlen), &flen)) {    //完成加密操作,处理剩余字节
        perror("\n Error,ENCRYPT_FINAL:");
        return -1;
    }
#else
	//remainder = outlen % 16;
	//memset(_pOutBuf + outlen, 0x00, remainder);
#endif

	outlen = outlen;
	printf("Encrypted Hexadecimal Unsigned Numbers: %d\n", outlen + flen);
    for ( i = 0; i < outlen + flen; i++) {
        printf("0x%02X,", _pOutBuf[i] & 0xFF);
    }
    printf("\n");

    EVP_CIPHER_CTX_cleanup(pEn_ctx);
 
    *_pOutLen = outlen + flen;
    return 0;               /* SUCCESS */
}
 
/*
*****************************************************************************************
*	函 数 名: aes_decrypt_string
*	功能说明: AES解密得到字符串
*	形    参:   _pPassword  :   密码
*               _pInput     :   输入需解密的数据
*               _InLen      :   输入需解密的数据长度
*               _pOutBuf    :   输出AES解密后的字符串
*               _pOutLen    :   输出AES编码数据长度
*	返 回 值: 0:成功, -1:失败
*****************************************************************************************
*/
int aes_decrypt_string(/*char *_pPassword, */char *_pInput, int _InLen, char *_pOutBuf, int *_pOutLen, unsigned char key[], unsigned char iv[])
{
    EVP_CIPHER_CTX *pDe_ctx;
    int flen = 0, outlen = 0;
    int i, nrounds = 1;
    //unsigned char key[32], iv[32];
    const EVP_CIPHER *cipherType = EVP_aes_256_cbc();
 
    if (/*_pPassword == NULL ||*/ _pInput == NULL || _pOutBuf == NULL || _pOutLen == NULL) {
        printf("_pInput == NULL\n");
		return -1;
    }
 
    /*
    * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material.
    * nrounds is the number of times the we hash the material. More rounds are more secure but
    * slower.
    */
    /*i = EVP_BytesToKey(cipherType, EVP_md5(), NULL, _pPassword, strlen(_pPassword), nrounds, key, iv);  //输入密码产生了密钥key和初始化向量iv
    if (i != 32) {
        printf("Key size is %d bits - should be 256 bits\n", i);
        return -1;
    }*/
 
    pDe_ctx = EVP_CIPHER_CTX_new();                             //创建加密上下文
 
    EVP_CIPHER_CTX_init(pDe_ctx);                               //初始化 EVP_CIPHER_CTX 上下文
    EVP_DecryptInit_ex(pDe_ctx, cipherType, NULL, key, iv);     //初始化解密操作
 
    /* Update cipher text */
    if (!EVP_DecryptUpdate(pDe_ctx, (unsigned char*)_pOutBuf, &outlen,(unsigned char*)_pInput, _InLen)) {   //处理数据
        perror("\n Error,ENCRYPR_UPDATE:");
		 printf("\n Error,ENCRYPR_UPDATE:\n");
        return -1;
    }
 
#if 1
    /* updates the remaining bytes */
    if (EVP_DecryptFinal_ex(pDe_ctx, (unsigned char*)(_pOutBuf + outlen), &flen) != 1) {    //完成加密操作,处理剩余字节
        perror("\n Error,ENCRYPT_FINAL:");
		printf("\n Error,ENCRYPT_FINAL:\n");
        return -1;
    }
#endif
 	outlen = outlen;
	/*printf("deccrypted Hexadecimal Unsigned Numbers: %d\n",outlen + flen);
    for ( i = 0; i < outlen + flen; i++) {
		printf("0x%02X,", _pOutBuf[i] & 0xFF);
    }
    printf("\n");
	*/
    EVP_CIPHER_CTX_cleanup(pDe_ctx);
 
    *_pOutLen = outlen + flen;
    return 0;               /* SUCCESS */
}

void addPadding(unsigned char *data, int len, int blockSize) {
    int padding = blockSize - (len % blockSize);
    if (padding > 0 && padding < blockSize) {
        memset(data + len, 0x00, padding);
    }
}
	const unsigned char key[] = "ac345874639cd8f21048792346aef453";
	const unsigned char iv[] = "763ab87fe92c4523";

int aes_encrypt(char* in, char* key, char* iv,char* out,int len)
{
    unsigned char lk_iv[16];
    AES_KEY aes;
	int i = 0;
    if(!in || !key || !out) return 0;
    if(AES_set_encrypt_key((unsigned char*)key, 256, &aes) < 0)
    {
        return 0;
    }
    memcpy(lk_iv, iv, 16);
    AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, lk_iv, AES_ENCRYPT);
	/*printf("lk_aes_encrypt: %d\n",len);
    for ( i = 0; i < len; i++) {
		printf("0x%02X,", out[i] & 0xFF);
    }
    printf("\n");
	*/
    return 1;
}
int aes_decrypt(char* in, char* key, char* iv,char* out,int len)
{
    unsigned char lk_iv[16];
    AES_KEY aes;
	int i = 0;
    if(!in || !key || !out) return 0;
    if(AES_set_decrypt_key((unsigned char*)key, 256, &aes) < 0)
    {
        return 0;
    }
    memcpy(lk_iv, iv, 16);
    AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, lk_iv, AES_DECRYPT);
	/*printf("dlk_aes_decrypt: %d\n",len);
    for ( i = 0; i < len; i++) {
		printf("0x%02X,", out[i] & 0xFF);
    }
    printf("\n");
	*/
    return 1;
}

#define ONLY_DEC 1
void test_ads()
{
	const unsigned char key[] = "ac345874639cd8f21048792346aef453";
	const unsigned char iv[] = "763ab87fe92c4523";
	int plaintext_len = 0;

    const unsigned char plaintext[] = {
		0x49,0x50,0x54,0x56,0x5F,0x43,0x4D,0x44,0xDC,0x01,0xA8,0xC0,0x23,0x2A,0x74,0x00,0xFF,0x00,0x35,0x34,0x52,0x58,0x2D,0x4D,0x41,0x54,0x52,0x49,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x01,0xA8,0xC0,0x23,0x29,0x00,0x02,0x00,0x01,0x00,0x01,0xE0,0x3B,0xC9,0xB7,0xDA,0xA4,0x01,0x00,0x5B, \
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	};
	//char _pOutBuf[] = {0x98,0x07,0x0C,0xC8,0x5E,0x5B,0xDE,0xE2,0x01,0xEA,0x87,0x2E,0x57,0x08,0xC1,0x94,0x5E,0xD0,0x7D,0x7C,0x59,0xAF,0xE4,0xE9,0xBA,0x05,0xD6,0xC8,0x80,0x5F,0x1D,0xE4,};
#if ONLY_DEC
	char _pOutBuf[] = {
		0x83,0xFA,0xC6,0xA4,0xE1,0xA5,0xBA,0x18,0xF8,0x3C,0xA5,0xC8,0xAB,0x81,0x73,0x50,0xAA,0xC1,0xE1,0x70,0x5A,0x19,0x08,0x2F,0x11,0xA2,0xE2,0x88,0xBA,0xED,0xAF,0xDD,0xE4,0xFD,0x54,0x8B,0x2C,0xA3,0xE5,0xB2,0xD6,0x4B,0x0D,0xEB,0x4E,0x80,0x79,0x77,0xF1,0x47,0xCE,0x14,0x7F,0xF1,0xE9,0x46,0xE8,0xA8,0x45,0xFD,0x9B,0x3D,0x47,0xD4,0x6B,0x65,0x28,0x6F,0xF4,0xCE,0x53,0xC2,0x86,0xD6,0x88,0x81,0x30,0xFB,0xF1,0x02,
	};
#else
	char _pOutBuf[1024] = {0};
#endif
	char _pdecOutBuf[1024] = {0};
	int _pOutLen = 0;
	
	int remainder = 0;
	int i = 0;

	plaintext_len = sizeof(plaintext);
#if !ONLY_DEC
	if (aes_encrypt_string(plaintext, plaintext_len, _pOutBuf, &_pOutLen, key, iv) != 0) {   //AES编码
       	printf("aes_encrypt_string failed\n");
        return -1;
    }
#endif
	printf("_pOutLen = %d,plaintext_len= %d, \n",_pOutLen, plaintext_len);
#if !ONLY_DEC
	if (aes_decrypt_string(_pOutBuf, _pOutLen, _pdecOutBuf, &_pOutLen, key, iv) != 0) {  
       	printf("aes_encrypt_string failed\n");
        return -1;
    }
#else
	/*if (aes_decrypt_string(_pOutBuf, sizeof(_pOutBuf), _pdecOutBuf, &_pOutLen, key, iv) != 0) {  
       	printf("aes_encrypt_string failed\n");
        return -1;
    }*/
	aes_decrypt(_pOutBuf, key, iv,_pdecOutBuf,sizeof(_pOutBuf));
#endif
}

aes_decrypt_string解密有问题,后用aes_decrypt解密解决问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值