书接上篇《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同目录下即可。