AES加密之openssl使用(2)

时间:2022-03-24 13:12:50

       书接上篇《AES加密只openssl安装》,在文章结尾简单列出了openssl接口使用,但是峰回路转旧的代码总是满足不了新的需求。我想将加密后的二进制数手动输入然后通过算法解密,怎么办,。。。。?使用base64啊。加密后的结果因为是二进制数字,而base64编码之中要求传入编码的长度,于是使用strlen就不怎么靠谱了,加密后的长度怎么求出。解决1.使用MD5加密为固定长度,缺点不可逆。2.memset为255(空格)吧

        且看代码:

linux版本suse下编译通过

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/aes.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/evp.h>


void Base64Encode(unsigned char *inputString, int inLen, unsigned char *outputString, int *outLen)
{
BIO *bmem = NULL;
BIO *b64 = NULL;
BUF_MEM *bptr = NULL;
if ((NULL == inputString) ||
(NULL == outputString))
{
return;
}

b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);

BIO_write(b64, inputString, inLen);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
if (bptr->length > *outLen)
{
*outLen = bptr->length;
return;
}

memcpy(outputString, bptr->data, bptr->length-1);
outputString[bptr->length-1] = 0;
*outLen = bptr->length-1;
BIO_free_all(b64);
return;
}
void Base64Decode(const char* inputString, int inLen, unsigned char* outputString, int *outLen)
{
BIO * b642 = NULL;
BIO * bmem2 = NULL;
char tmp[inLen + 1];
if(NULL == inputString || NULL == outputString)
{
return;
}

tmp[inLen] = '\n'; /*Openssl demand to have '\n' to end the string.*/
memcpy(&tmp[0], inputString, inLen);
memset(outputString, 0 , *outLen);

b642 = BIO_new(BIO_f_base64());
bmem2 = BIO_new_mem_buf(&tmp[0], inLen+1);
bmem2 = BIO_push(b642, bmem2);
*outLen = BIO_read(bmem2, outputString, *outLen);
BIO_free_all(bmem2);
return ;
}

void aes_box_encrypt(unsigned char* source_string, unsigned char* des_string)
{
int iLoop = 0;
int iLen =0;
AES_KEY aes;
unsigned char key[AES_BLOCK_SIZE];
unsigned char iv[AES_BLOCK_SIZE];
if(NULL == source_string || NULL == des_string)
{
return;
}

//Generate own AES Key
memcpy(key,"1234567890123456",AES_BLOCK_SIZE);

// Set encryption key
for (iLoop=0; iLoop<AES_BLOCK_SIZE; iLoop++)
{
iv[iLoop] = 0;
}

if (AES_set_encrypt_key(key, 128, &aes) < 0)
{
return ;
}

iLen = strlen(source_string)+1;

AES_cbc_encrypt(source_string, des_string, iLen, &aes, iv, AES_ENCRYPT);

}
void aes_box_decrypt(unsigned char* source_string, unsigned char* des_string)
{
int iLoop = 0;
int iLen =0;
AES_KEY aes;
unsigned char key[AES_BLOCK_SIZE];
unsigned char iv[AES_BLOCK_SIZE];
if(NULL == source_string || NULL == des_string)
{
return;
}

//Generate own AES Key
memcpy(key,"1234567890123456",AES_BLOCK_SIZE);

// Set encryption key
for (iLoop=0; iLoop<AES_BLOCK_SIZE; iLoop++)
{
iv[iLoop] = 0;
}

if (AES_set_decrypt_key(key, 128, &aes) < 0)
{
return ;
}

iLen = strlen(source_string)+1;

AES_cbc_encrypt(source_string, des_string, iLen, &aes, iv, AES_DECRYPT);
}
int main(int argc,char *argv[])
{
unsigned char ucIsEncrypt = 3;
unsigned char sourceStringTemp[100];
unsigned char dstStringTemp[100];
unsigned char printString[100];
unsigned long ulBase64SrcLen = 0;
unsigned long ulBase64DstLen = 100;

memset(sourceStringTemp, 0 ,100);
memset(dstStringTemp, 0 ,100);
memset(printString, 0, 100);


strcpy((char*)sourceStringTemp, argv[1]);
ucIsEncrypt = atoi(argv[2]);

if(AES_ENCRYPT == ucIsEncrypt)
{
aes_box_encrypt(sourceStringTemp,dstStringTemp);

ulBase64SrcLen = strlen(dstStringTemp);
Base64Encode(dstStringTemp, ulBase64SrcLen , printString, &ulBase64DstLen);
printf("%s\r\n", printString);

}
else if(AES_DECRYPT == ucIsEncrypt)
{
ulBase64SrcLen = strlen(sourceStringTemp);
Base64Decode(sourceStringTemp, ulBase64SrcLen, printString, &ulBase64DstLen);
aes_box_decrypt(printString,dstStringTemp);

printf("%s\r\n", dstStringTemp);
}

return 0;
}

关于带参数main函数使用问题: 

gcc AESPassword.c -o AESPassword

./AESPassword icd 1

window下VS2008编译通过

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "openssl/aes.h"

#include "openssl/pem.h"
#include "openssl/bio.h"
#include "openssl/evp.h"
#pragma comment(lib, "4758cca.lib")
#pragma comment(lib, "aep.lib")
#pragma comment(lib, "atalla.lib")
#pragma comment(lib, "4758cca.lib")
#pragma comment(lib, "chil.lib")
#pragma comment(lib, "capi.lib")
#pragma comment(lib, "cswift.lib")
#pragma comment(lib, "gmp.lib")
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "nuron.lib")
#pragma comment(lib, "padlock.lib")
#pragma comment(lib, "ssleay32.lib")
#pragma comment(lib, "gost.lib")
#pragma comment(lib, "sureware.lib")
#pragma comment(lib, "ubsec.lib")


void Base64Encode(unsigned char *inputString, int inLen, unsigned char *outputString, int *outLen)
{
BIO *bmem = NULL;
BIO *b64 = NULL;
BUF_MEM *bptr = NULL;
if ((NULL == inputString) ||
(NULL == outputString))
{
return;
}

b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);

BIO_write(b64, inputString, inLen);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
if (bptr->length > *outLen)
{
*outLen = bptr->length;
return;
}

memcpy(outputString, bptr->data, bptr->length-1);
outputString[bptr->length-1] = 0;
*outLen = bptr->length-1;
BIO_free_all(b64);
return;
}
void Base64Decode(const char* inputString, int inLen, unsigned char* outputString, int *outLen)
{
BIO * b642 = NULL;
BIO * bmem2 = NULL;
char tmp[50 + 1];
if(NULL == inputString || NULL == outputString)
{
return;
}

tmp[inLen] = '\n'; /*Openssl demand to have '\n' to end the string.*/
memcpy(&tmp[0], inputString, inLen);
memset(outputString, 0 , *outLen);

b642 = BIO_new(BIO_f_base64());
bmem2 = BIO_new_mem_buf(&tmp[0], inLen+1);
bmem2 = BIO_push(b642, bmem2);
*outLen = BIO_read(bmem2, outputString, *outLen);
BIO_free_all(bmem2);
return ;
}

void aes_box_encrypt(unsigned char* source_string, unsigned char* des_string)
{
int iLoop = 0;
int iLen =0;
AES_KEY aes;
unsigned char key[AES_BLOCK_SIZE];
unsigned char iv[AES_BLOCK_SIZE];
if(NULL == source_string || NULL == des_string)
{
return;
}

//Generate own AES Key
memcpy(key,"1234567890123456",AES_BLOCK_SIZE);

// Set encryption key
for (iLoop=0; iLoop<AES_BLOCK_SIZE; iLoop++)
{
iv[iLoop] = 0;
}

if (AES_set_encrypt_key(key, 128, &aes) < 0)
{
return ;
}

iLen = strlen(source_string)+1;

AES_cbc_encrypt(source_string, des_string, iLen, &aes, iv, AES_ENCRYPT);

}
void aes_box_decrypt(unsigned char* source_string, unsigned char* des_string)
{
int iLoop = 0;
int iLen =0;
AES_KEY aes;
unsigned char key[AES_BLOCK_SIZE];
unsigned char iv[AES_BLOCK_SIZE];
if(NULL == source_string || NULL == des_string)
{
return;
}

//Generate own AES Key
memcpy(key,"1234567890123456",AES_BLOCK_SIZE);

// Set encryption key
for (iLoop=0; iLoop<AES_BLOCK_SIZE; iLoop++)
{
iv[iLoop] = 0;
}

if (AES_set_decrypt_key(key, 128, &aes) < 0)
{
return ;
}

iLen = strlen(source_string)+1;

AES_cbc_encrypt(source_string, des_string, iLen, &aes, iv, AES_DECRYPT);
}
int main(int argc,char *argv[])
{
unsigned char ucIsEncrypt = 3;
unsigned char sourceStringTemp[100];
unsigned char dstStringTemp[100];
unsigned char printString[100];
unsigned long ulBase64SrcLen = 0;
unsigned long ulBase64DstLen = 100;
unsigned long ulPrintLen = 0;

memset(sourceStringTemp, 0 ,100);
memset(dstStringTemp, 255 ,100);
memset(printString, 0, 100);

if(argc < 2)
{
return 0;
}

strcpy((char*)sourceStringTemp, argv[1]);
ucIsEncrypt = atoi(argv[2]);

if(AES_ENCRYPT == ucIsEncrypt)
{
aes_box_encrypt(sourceStringTemp,dstStringTemp);

for (; 255!=dstStringTemp[ulBase64SrcLen]; ulBase64SrcLen++);

Base64Encode(dstStringTemp, ulBase64SrcLen , printString, &ulBase64DstLen);
printf("%s\r\n", printString);

}
else if(AES_DECRYPT == ucIsEncrypt)
{
ulBase64SrcLen = strlen(sourceStringTemp);
Base64Decode(sourceStringTemp, ulBase64SrcLen, printString, &ulBase64DstLen);
aes_box_decrypt(printString,dstStringTemp);
ulPrintLen = strlen(dstStringTemp);
dstStringTemp[ulPrintLen]='\0';

printf("%s", dstStringTemp);
}

return 0;
}

同上,vs2008命令提示符进入AESPassword.exe当前目录:

AESPassword.exe icd 1

1为加密,0为解密
 

错误:32位机器正常运行,但是在64位机器上面有“readyX.dll”错误

工程属性——》配置属性——》C/C++——》常规——》检测64位可移植性问题

另外:

工程属性——》配置属性——》常规——》MFC的使用——》在静态库中使用MFC

 

错误:在机器中运行AESPassword.exe,出现缺少“libeay32.dll”文件

libeay32.dll文件为openssl源程序编译后的文件,将其放在AESPassword.exe同目录下即可。