我想在我的c ++应用程序中加密和解密字符串,并使用openssl。 因为我不知道该怎么做,我使用了来自互联网的代码:
LPCTSTR encrypt(LPCTSTR inString, LPCTSTR inKey, LPCTSTR outString)
{
const unsigned char* inStringC = (const unsigned char*)inString;
const unsigned char* outStringC = (const unsigned char*)outString;
const unsigned char* inKeyC = (const unsigned char*)inKey;
HINSTANCE libeay32 = LoadLibrary("libeay32.dll");
GET_FUNC_PTR(BF_set_key, void, void*, int, const unsigned char*);
GET_FUNC_PTR(BF_cfb64_encrypt, void, unsigned char*, unsigned char*, long, void*, unsigned char*, int*, int);
if (BF_set_key == NULL || BF_cfb64_encrypt == NULL) {
TRACE("ERROR: failed while loading functions from \"libeay32.dll\"\n");
return NULL;
}
BF_KEY key = {NULL, NULL};
BF_set_key(&key, strlen((const char*)inKeyC), inKeyC);
size_t length = strlen(inString);
unsigned char *cfb64_out = (unsigned char*)malloc((length+2)*sizeof(unsigned char*));
unsigned char iv[32];
memset(cfb64_out,0,length+1);
memset(iv,0,32);
int num = 0;
BF_cfb64_encrypt((unsigned char*)inStringC, cfb64_out, length, &key, iv, &num, BF_ENCRYPT);
FreeLibrary(libeay32);
std::string retString = base64_encode((const char *)cfb64_out);
strcpy((char*)outStringC, retString.c_str());
free(cfb64_out);
return outString;
}
LPCTSTR decrypt(LPCTSTR inString, LPCTSTR inKey, LPCTSTR outString)
{
const unsigned char* inStringC = (const unsigned char*)inString;
const unsigned char* outStringC = (const unsigned char*)outString;
const unsigned char* inKeyC = (const unsigned char*)inKey;
HINSTANCE libeay32 = LoadLibrary("libeay32.dll");
GET_FUNC_PTR(BF_set_key, void, void*, int, const unsigned char*);
GET_FUNC_PTR(BF_cfb64_encrypt, void, unsigned char*, unsigned char*, long, void*, unsigned char*, int*, int);
if (BF_set_key == NULL || BF_cfb64_encrypt == NULL) {
TRACE("ERROR: failed while loading functions from \"libeay32.dll\"\n");
return NULL;
}
BF_KEY key = {NULL, NULL};
BF_set_key(&key, strlen((const char*)inKeyC), inKeyC);
std::string retString = base64_decode((const char*)inStringC);
size_t length = retString.length();
unsigned char *cfb64_out = (unsigned char*)malloc((length+2)*sizeof(unsigned char));
unsigned char iv[32];
memset(cfb64_out,0,length+1);
memset(iv,0,32);
int num = 0;
BF_cfb64_encrypt((unsigned char * )retString.c_str(), cfb64_out, length, &key, iv, &num, BF_DECRYPT);
FreeLibrary(libeay32);
strcpy((char *)outStringC, (char *)cfb64_out);
free(cfb64_out);
return outString;
}
这大多数时候都有用。但有时没有。例如输入“as”和键“hfsa”失败。因为我确信openssl正在工作,我想我在调用openssl函数时做错了。任何想法?
编辑: “失败”表示加密字符串为空或解密字符串为空。大多数情况下,当它失败时,解密的字符串只是预期的子字符串。
EDIT2:
我把问题解决了这个问题:
如果我使用键“dg”加密例如“sdg”,那么使用openssl函数
BF_cfb64_encrypt((char * )inputStr, cfb64_out, length, &key, iv, &num, BF_ENCRYPT);
返回长度为2的“ƒx”。当我解码时,我必须告诉openssl的解密函数(见上文)解密的长度。这是2.
但原始字符串的长度为3.所以我只得到“sd”作为解密结果而不是“sdg”。
答案 0 :(得分:1)
char *在面向字节的加密中的工作方式与字符串不同。通常它保存空终止字符串。在这种情况下它没有,它保持一个定义长度的字节数组(在你的情况下为3)。其中的字节可以包含任何值,包括 00h,空终止字符,具体取决于密钥,数据和IV。所以你只需要记住(使用CFB)你的输入长度 你的输出长度,并在解密时指定特定的长度(换句话说,你需要传达长度在进行加密的部分和进行解密的部分之间。