C ++ OpenSSL усечение ввода JSON - PullRequest
1 голос
/ 10 апреля 2019

Я работаю над проектом, который включает в себя шифрование строки json (длиной более 4000 символов), а затем расшифровку ее после отправки POST в PHP через CURL. У меня есть библиотека openssl, работающая и компилирующая, она может сохранять аналогичные данные json, зашифрованные в двоичном файле, читать, дешифровать и использовать их. Как только я только пытаюсь зашифровать строку и отправить ее, openssl обрезает данные. Данные содержат специальные символы (utf8mb4), но, поскольку запись в файл выполняется очень хорошо, я не понимаю, почему отказывается шифровать всю строку. Я попробовал следующее с 32-байтовым (256-битным) ключом и 16-байтовым (128-битным) iv:

AES-256-CBC AES-256-ЦКС AES-256-ECB AES-256-GCM

Короткие строки работают нормально (то есть <175 символов). Но более длинные строки, такие как полезная нагрузка JSON, не работают. Даже собственный пример кода openssl не шифрует полезную нагрузку. </p>

Основная функция (для тестирования): https://pastebin.com/ZrpSd88W

int main()
{
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    /* Set up the key and iv. Do I need to say to not hard code these in a real application? :-) */

    /* A 256 bit key */
    static const unsigned char key[] = "01234567890123456789012345678901";

    /* A 128 bit IV */
    static const unsigned char iv[] = "0123456789012345";

    /* Message to be encrypted */
    unsigned char plaintext[] = "The quick brown fox jumps over the lazy dog";

    /* Some additional data to be authenticated */
    static const unsigned char aad[] = "Some AAD data";





    int decryptedtext_len = 0, ciphertext_len = 0;


    printf("");
    printf("");
    printf("");
    printf("");
    printf("");
    printf("");
    printf("");

    curl_global_init(CURL_GLOBAL_ALL);


    std::string data = "{ \"jobData\": {\"isMultiplayer\": false,\"late\": false,\"sourceCity\": \"Düsseldorf\",\"sourceCompany\": \"Stokes\",\"destinationCity\": \"Duisburg\",\"destinationCompany\": \"LkwLog GmbH\",\"cargo\": \"Wheat\",\"truckMake\": \"Volvo\",\"truckModel\": \"FH16 Classic\",\"game\": \"Euro Truck Simulator 2\",\"sourceCityID\": \"dusseldorf\",\"sourceCompanyID\": \"stokes\",\"destinationCityID\": \"duisburg\",\"destinationCompanyID\": \"lkwlog\",\"cargoID\": \"wheat\",\"truckMakeID\": \"volvo\",\"truckModelID\": \"vehicle.volvo.fh16\",\"gameID\": \"ets2\",\"gameVersion\": \"1.13\",\"pluginVersion\": \"0.15.365.0\",\"income\": 799,\"trailerMass\": 17140,\"distanceDriven\": 7.56641,\"fuelBurned\": 4.75964,\"fuelPurchased\": 0,\"startOdometer\": 64493,\"endOdometer\": 64500.6,\"collisionCount\": 3,\"finishTrailerDamage\": 0.0201135,\"startTrailerDamage\": 0,\"deliveryX\": -13184.1,\"deliveryY\": 58.2873,\"deliveryZ\": -6147.25,\"pickupX\": -13147.2,\"pickupY\": 48.0304,\"pickupZ\": -4555.74,\"trailerDeliveryX\": -13184.2,\"trailerDeliveryY\": 58.2863,\"trailerDeliveryZ\": -6152.03,\"trailerPickupX\": -13147.2,\"trailerPickupY\": 48.0285,\"trailerPickupZ\": -4560.52,\"startEngineDamage\": 0,\"startTransmissionDamage\": 0,\"startCabinDamage\": 0,\"startChassisDamage\": 0,\"startWheelDamage\": 0,\"finishEngineDamage\": 0.0138086,\"finishTransmissionDamage\": 0.00829076,\"finishCabinDamage\": 0.0220714,\"finishChassisDamage\": 0.0275892,\"finishWheelDamage\": 0.00427838,\"totalEngineDamage\": 0.0138086,\"totalTransmissionDamage\": 0.00829076,\"totalCabinDamage\": 0.0220714,\"totalChassisDamage\": 0.0275892,\"totalWheelDamage\": 0.00427838,\"totalTrailerDamage\": 0.0201135,\"osEnvironment\": \"Windows\",\"architecture\": \"x64\",\"steamID\": \"xxx\",\"steamUsername\": \"xxx\",\"navigationDistanceRemaining\": 160.393,\"teleported\": true}}";



    unsigned char a[KEY_SIZE+1];
    unsigned char b[IV_SIZE + 1];


    for (int i = 0; i < KEY_SIZE; i++)
        a[i] = 'a';
    for (int i = 0; i < IV_SIZE; i++)
        b[i] = 'b';
    a[KEY_SIZE] = '\0';
    b[IV_SIZE] = '\0';


    int predicted_len = strlen(data.c_str()) + (BLOCK_SIZE - (strlen(data.c_str()) % BLOCK_SIZE));
    predicted_len = strlen(data.c_str());
    unsigned char* encrypted = new unsigned char[predicted_len+1];
    std::string hex2 = NewMessage::StrToHex(a);
    std::string hex3 = NewMessage::StrToHex(b);
    //int encrypted_len = NewMessage::encryptcbc((unsigned char*)data.c_str(), strlen(data.c_str()), a, b, encrypted);
    int encrypted_len = NewMessage::encrypt((unsigned char*)data.c_str()+'\0', strlen(data.c_str()), a,b, encrypted);

    encrypted[predicted_len] = '\0';
    std::string hex = NewMessage::StrToHex(encrypted);

    std::cout << std::endl << std::endl << std::endl << std::endl;
    std::cout << hex << std::endl;
    std::cout << std::endl << std::endl << std::endl << std::endl;
    std::cout << hex2;
    std::cout << std::endl << std::endl << std::endl << std::endl;
    std::cout << hex3;
    std::cout << std::endl << std::endl << std::endl << std::endl;

    data.clear();
    //delete[] encrypted;
    /*----------------------------------------------------------------------*/
    data = "";

    curl_global_cleanup();
    /* Remove error strings */

    ERR_free_strings();
    return 0;
}

Функция шифрования:

    int encrypt(unsigned char* plaintext, int plaintext_len,  unsigned char* key, unsigned char* iv, unsigned char* ciphertext)
    {
        EVP_CIPHER_CTX* ctx = NULL;
        int len = 0, ciphertext_len = 0;

        /* Create and initialise the context */
        if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

        /* Initialise the encryption operation. */
        if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, iv))
            handleErrors();


        if (plaintext)
        {
            if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
                handleErrors();

            ciphertext_len = len;
        }

        if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
        ciphertext_len += len;

        EVP_CIPHER_CTX_free(ctx);

        return ciphertext_len;
    }

Я заблудился, почему data никогда не шифруется полностью, даже если ciphertext_len возвращает правильное значение. Если бы кто-нибудь мог указать мне правильное направление, это было бы здорово.

1 Ответ

0 голосов
/ 10 апреля 2019

Я получил его для успешной работы, другой разработчик на С ++ помог мне исправить проблемы с методом StrToHex, который я использовал. Рассматриваемый метод (фиксированный) размещен ниже:

std::string StrToHex(const std::string& in)
        {
            std::string csHexString;
            for (unsigned int i = 0; i < in.size(); i++)
            {
                char tmp[10];
                int len = sprintf(tmp, "%02X", (in[i] & 0xFF));
                csHexString += std::string(tmp, len);
            }
            return csHexString;
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...