C - шифрование OpenSSL с использованием режима CBC (Cipher Block Chaining) - PullRequest
0 голосов
/ 03 октября 2018

Я использую C-API OpenSSL , но я не совсем понимаю, как IV ( Вектор инициализации ) используется в OpenSSL.

Скажите, у меня есть

plaintext.txt file = "This is a top secret."
Key                = "example#########"
IV                 = 010203040506070809000a0b0c0d0e0f

, когда я шифрую это с помощью OpenSSL AES-128-CBC , я должен получить:

e5accdb667e8e569b1b34f423508c15422631198454e104ceb658f5918800c22

Что верно, когдаЯ пытаюсь это (ключ преобразуется в шестнадцатеричный):

openssl enc -aes-128-cbc -e -in plaintext.txt -out ciphertext.bin 
-K 6578616d706c65232323232323232323 -iv 010203040506070809000a0b0c0d0e0f

Я получаю:

xxd -p ciphertext.bin 
e5accdb667e8e569b1b34f423508c15422631198454e104ceb658f5918800c22

Но я получил зашифрованный текст вещь с использованием C

char plaintext[] = "This is a top secret.";

unsigned char iv[16] = {
    0x01, 0x02, 0x03, 0x04, 
    0x05, 0x06, 0x07, 0x08, 
    0x09, 0x00, 0x0A, 0x0B, 
    0x0C, 0x0D, 0x0E, 0x0F
};

unsigned char ciphertext[] = {
    0xe5, 0xac, 0xcd, 0xb6, 
    0x67, 0xe8, 0xe5, 0x69, 
    0xb1, 0xb3, 0x4f, 0x42, 
    0x35, 0x08, 0xc1, 0x54, 
    0x22, 0x63, 0x11, 0x98, 
    0x45, 0x4e, 0x10, 0x4c, 
    0xeb, 0x65, 0x8f, 0x59, 
    0x18, 0x80, 0x0c, 0x22
};

ключ (пример) находится в words.txt файле.


Мой процесс шифрования:

while(fgets(words, 16, wordsfile)) { //for getting key and padding
    index = strlen(words) - 1;       //key "example" is the last word in words.txt
    while(index < 16) {
        words[index] = 0x20;
        index++;
    }
    words[index] = '\0';
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, words, iv, 1);
    EVP_CipherUpdate(&ctx, outbuf, &outlen, plaintext, strlen(plaintext));
    EVP_CipherFinal_ex(&ctx, outbuf + outlen, &templ);
    outlen += templ;
    EVP_CIPHER_CTX_cleanup(&ctx);
}

Когда я проверяю совпадения зашифрованного текстаК ключевому «примеру» я получил совершенно другой зашифрованный текст.В какой части я ошибся?Я предполагаю, что формат IV или способ, которым я внедрил IV, неправильный.

1 Ответ

0 голосов
/ 03 октября 2018

Похоже, вы довольно близко.Сузив проблему до простого шифрования, можно получить правильный зашифрованный текст.Поэтому вместо чтения ключа из файла определите его как массив знаков без знака, аналогично тому, что вы сделали для других переменных:

unsigned char key[]={0x65,0x78,0x61,0x6d,0x70,0x6c,0x65,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23};

Затем следующий код (повторное использование ваших переменных) показываетуспешное шифрование:

EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(),NULL, key, iv, 1);
EVP_CipherUpdate(&ctx, outbuf, &outlen, (unsigned char *)plaintext, strlen(plaintext));
EVP_CipherFinal_ex(&ctx, outbuf+outlen, &templ);
outlen+=templ;
EVP_CIPHER_CTX_cleanup(&ctx);
int cmpres = memcmp(outbuf, ciphertext, sizeof(ciphertext));
printf("cmpres is %d, sizeof(ciphertext) is %lu, outlen is %d\n",
    cmpres, sizeof(ciphertext), outlen);

, поскольку оно печатает

$ ./main
cmpres is 0, sizeof(ciphertext) is 32, outlen is 32

Это означает, что проблема заключается в том, как вы читаете ключ из файла.Это гораздо проще проанализировать, чем криптографические проблемы :-), и я оставлю на ваше усмотрение выяснить эту часть ...

Кстати, обязательно проверьте все коды возврата для ваших вызовов OpenSSL,это поможет вам обнаружить ошибки ситуации.

...