#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解密解决问题