簡體   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