Недостающий последний шаг шифра

Вы не выполняете последний шаг после шагов обновления для шифрования или дешифрования данных

Описание

Недостающий последний шаг шифра происходит, когда вы не выполняете последний шаг после своих шагов обновления для шифрования или дешифрования данных.

Например, вы делаете следующее:

/* Initialization of cipher context */
ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
...
/* Update step */
ret = EVP_EncryptUpdate(&ctx, out_buf, &out_len, src, len);
...
/* Missing final step */
...
/* Cleanup of cipher context */
EVP_CIPHER_CTX_cleanup(ctx);

Риск

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

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

Фиксация

После ваших шагов обновления для шифрования или дешифрования, выполните последний шаг, чтобы зашифровать или дешифровать оставшиеся данные.

/* Initialization of cipher context */
ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
...
/* Update step(s) */
ret = EVP_EncryptUpdate(&ctx, out_buf, &out_len, src, len);
...
/* Final step */
ret = EVP_EncryptFinal_ex(&ctx, out_buf, &out_len);
...
/* Cleanup of cipher context */
EVP_CIPHER_CTX_cleanup(ctx);

Примеры

развернуть все


#include <openssl/evp.h>
#include <stdlib.h>
#define SIZE16 16

unsigned char *out_buf;
int out_len;
unsigned char key[SIZE16];
unsigned char iv[SIZE16];

void func(unsigned char *src, int len) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);

    /* Initialization of cipher context */
    EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    
    /* Update steps for encryption */
    EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len);   
    
    /* Missing final encryption step */
    
    /* Cleanup of cipher context */
    EVP_CIPHER_CTX_cleanup(ctx); 
}

В этом примере контекст шифра ctx очищен перед итоговым шагом шифрования. Последний шаг, как предполагается, шифрует оставшиеся данные. Без последнего шага шифрование является неполным.

Исправление — выполняет итоговый шаг шифрования

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


#include <openssl/evp.h>
#include <stdlib.h>
#define SIZE16 16

unsigned char *out_buf;
int out_len;
unsigned char key[SIZE16];
unsigned char iv[SIZE16];

void func(unsigned char *src, int len) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);

    /* Initialization of cipher context */
    EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    
    /* Update steps for encryption */
    EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len);   
    
    /* Final encryption step */
    EVP_EncryptFinal_ex(ctx, out_buf, &out_len);
    
    /* Cleanup of cipher context */
    EVP_CIPHER_CTX_cleanup(ctx); 
}

Информация о результате

Группа: криптография
Язык: C | C++
Значение по умолчанию: 'off'
Синтаксис командной строки: CRYPTO_CIPHER_NO_FINAL
Влияние: носитель
ID CWE: 311, 325, 372, 664

Введенный в R2017a