Что эквивалентно моей openssl cmdline в C? - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь реализовать следующую командную строку openssl в C:

openssl enc -aes-256-cbc -d -in /tmp/out_enc -K \
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA \
    -iv 0 -nopad -p

Вывод командной строки:

key=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
iv =00000000000000000000000000000000
<CONNECTION_REQUEST ATS_ID="2" ATP_SEQ_ID="1" REGISTRATION_ID="Y2G5R52S8PP6YX47" SERIAL_NUMBER="724574802" SPC_PRODUCT_TITLE="SPC5300" SPC_FW_VERSION="3.8.5 - R.31629" ATS_NAME="Syst&#232;me (ATS) 2" ATP1_ID="2" ATP1_UID="34" ATP1_NAME="Principal ATP 1" ATP1_COMMS_INTERFACE="1" ATP1_DEST="1, 192.168.1.62:52000" ATP1_CATEGORY="50"/>�z

Это мой эквивалент в C:

long
_ast_crypt_decrypt_generic(unsigned char* ciphertext, long cipherlen, unsigned char* plaintext, const EVP_CIPHER *cipher) {
    long result = 0;

     /* A 256 bit key */
unsigned char *key = (unsigned char *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";

/* A 128 bit IV */
unsigned char *iv = (unsigned char *)"0000000000000000";
    EVP_CIPHER_CTX *ctx = NULL;
    int len;
    long plaintext_len;

    if (cipher) {
        /* Create and initialise the context */
        if (!(ctx = EVP_CIPHER_CTX_new())) {
            g_warning("AstCrypt : EVP_CIPHER_CTX_new failed");
            goto end;
        }

        if (1 != EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv)) {
            g_warning("AstCrypt : EVP_DecryptInit_ex");
        }

        EVP_CIPHER_CTX_set_padding(ctx, 0);

        if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, cipherlen)) {
            g_warning("AstCrypt : EVP_DecryptUpdate");
            goto end;
        }
        plaintext_len = len;

        if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) {
             g_warning("AstCrypt : EVP_DecryptFinal_ex failed");
             goto end;
        }
        plaintext_len += len;

        result= plaintext_len;
    } 
    else {
        g_warning("AstCrypt : Failed to get the openssl elements.");
    }

end:
    if (ctx)
        EVP_CIPHER_CTX_free(ctx);

    return result;
}

long plainSize = _ast_crypt_decrypt_generic(headerData, headerLength, bPlain, EVP_aes_256_cbc());
 //fwrite(bPlain, plainSize, 1, stdout);

Предыдущий пример кода неправильно расшифровывает данные (в C).

У вас есть идеи, что мне не хватает?

Вероятно, отсутствует понимание формата ключа / iv в openssl lib.

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

Ответ заключается в том, что ключ / iv должен быть представлен в шестнадцатеричном виде:

Следующее работает, как и ожидалось:

unsigned char key[] =
        {   0xAA, 0xAA, 0xAA, 0xAA,
        0xAA, 0xAA, 0xAA, 0xAA,
        0xAA, 0xAA, 0xAA, 0xAA,
        0xAA, 0xAA, 0xAA, 0xAA,
        0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,0 };
//unsigned char key[] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
    /* A 128 bit IV */
    unsigned char iv[] =
        {   0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,0 };
0 голосов
/ 29 февраля 2020

Проблема в том, что вы предполагаете, что ключ является прямой копией «пароля». То, что вы делаете с этой командной строкой, указывает ключ в виде шестнадцатеричной строки. Итак, что вам нужно сделать, это преобразовать ваш «пароль» из шестнадцатеричной строки в буфер ключей. В вашем примере вы должны получить каждый байт, установленный в шестнадцатеричное значение "0xAA".

Поскольку вы передаете ключ напрямую, вам не нужен параметр MD5 (для вашей функции или для openssl). ,

Если вы хотите использовать пароль вместо "шестнадцатеричной строки", то вам нужно как-то sh ввести его в буфер ключей. Вот тут-то и появляется параметр MD5. Вы можете использовать что-то вроде PBKDF2 (хотя я бы использовал SHA256 по умолчанию openssl, а не MD5 в качестве функции хеширования).
Например, openssl en c -aes-256-cb c -pbkdf2 -k пароль

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