c ++ openssl加密有时会失败

时间:2011-08-15 12:30:18

标签: c++ encryption 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函数时做错了。任何想法?

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

EDIT2:
我把问题解决了这个问题:
如果我使用键“dg”加密例如“sdg”,那么使用openssl函数

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

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

1 个答案:

答案 0 :(得分:1)

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