c++ openssl 加密有时会失败
我想在我的 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 函数时做错了什么。有什么想法吗?
编辑: “失败”意味着加密的字符串为空或解密的字符串为空。大多数时候,当它失败时,解密的字符串只是预期的子字符串。
编辑2:
我将问题隔离于此:
例如,如果我使用密钥“dg”加密“sdg”,则 openssl 函数
BF_cfb64_encrypt((char * )inputStr, cfb64_out, length, &key, iv, &num, BF_ENCRYPT);
返回长度为 2 的“fx”。
当我解码时,我必须告诉 openssl 的解密函数(见上文)长度解密。这是2。
但原始字符串的长度为3。所以我只得到“sd”作为解密结果而不是“sdg”。
i want to encrypt and decrypt strings in my c++ appication and use openssl for that.
since i don't know exactly how to do it, i used this code from the internet:
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;
}
this works most times. but some times not.for example with the input "as" and the key "hfsa" it fails. since i am sure openssl is working i guess i did something wrong in calling the openssl functions. any ideas?
edit:
"it fails" means that either the encrypted string is empty or the decrypted string is empty. most times when it fails the decrypted string is only a substring of the expected.
edit2:
i isolated the problem to this:
if i encrypt for example "sdg" with the key "dg" then the openssl function
BF_cfb64_encrypt((char * )inputStr, cfb64_out, length, &key, iv, &num, BF_ENCRYPT);
return "ƒx" which has the length 2.
when i decode that i have to tell the decrypt function of openssl (see above) the length to decrypt. this is 2.
but the original string had length 3. so i get only "sd" as decryption result instead of "sdg".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
char* 在面向字节的加密中的工作方式与在字符串中的工作方式不同。通常它保存以空结尾的字符串。在这种情况下,它没有,它保存一个确定长度的字节数组(在你的例子中是3)。其中的字节可以是任何值,包括 00h(空终止符),具体取决于密钥、数据和 IV。因此,您只需要记住(使用 CFB)您的输入长度是您的输出长度,并在解密时指定该特定长度(换句话说,您需要传达长度 > 进行加密的部分和进行解密的部分之间)。
char* works differently within byte oriented encryption than for strings. Normally it holds null terminated strings. In this case it doesn't, it holds a byte array of definate length (3 in your case). The bytes in it can have any value including 00h, the null termination character, depending on the key, the data and the IV. So you just need to remember that (with CFB) your input lenght is your output length, and specify that particular length when decrypting (in other words, you need to communicate the length between the part that does the encryption and the part that does the decryption).