繁体   English   中英

c++ openssl 加密有时会失败

[英]c++ openssl encryption fails sometimes

我想在我的 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 函数时做错了。 有任何想法吗?

编辑:“失败”表示加密字符串为空或解密字符串为空。 大多数情况下,解密字符串失败时只是预期的 ZE83AED3DDF4667DEC0DAAAACB2BB3BE0BZ。

编辑2:
我将问题隔离为:
如果我使用密钥“dg”加密例如“sdg”,那么 openssl function

                BF_cfb64_encrypt((char * )inputStr, cfb64_out, length, &key, iv, &num, BF_ENCRYPT);

返回长度为 2 的 "ƒx"。
当我解码时,我必须告诉 openssl 的解密 function(见上文)要解密的长度。 这是2。
但原始字符串的长度为 3。所以我只得到“sd”作为解密结果,而不是“sdg”。

char* 在面向字节的加密中的工作方式与在字符串中的工作方式不同。 通常它包含 null 终止的字符串。 在这种情况下,它没有,它包含一个确定长度的字节数组(在您的情况下为 3)。 其中的字节可以具有任何值,包括00h、null 终止字符,具体取决于密钥、数据和 IV。 因此,您只需要记住(使用 CFB)您的输入长度您的 output 长度,并在解密时指定该特定长度(换句话说,您需要在执行加密的部分和执行加密的部分之间传达长度解密)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM