C ++ OpenSSL шифрование иногда не удается - PullRequest
0 голосов
/ 15 августа 2011

Я хочу зашифровать и расшифровать строки в моем приложении 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:
я выделил проблему этому:
если я шифрую, например, «sdg» ключом «dg», то функция openssl

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

возвращает "ƒx", который имеет длину 2.
, когда я декодирую, что я должен сообщить функции дешифрования openssl (см. Выше) длину для дешифрования. это 2.
, но исходная строка имела длину 3. поэтому я получаю только "sd" в качестве результата расшифровки вместо "sdg".

1 Ответ

1 голос
/ 16 августа 2011

char * работает в байтовом шифровании иначе, чем для строк.Обычно он содержит строки с нулевым символом в конце.В этом случае это не так, он содержит байтовый массив определенной длины (3 в вашем случае).Байты в нем могут иметь любое значение , включая 00h, нулевой символ завершения, в зависимости от ключа, данных и IV.Так что вам просто нужно помнить, что (с CFB) ваша длина ввода равна вашей длины вывода, и указывать эту конкретную длину при расшифровке (другими словами, вам нужно сообщить длину междучасть, которая выполняет шифрование, и часть, которая выполняет расшифровку).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...