Если входная длина делится на размер блока, блок заполнение ожидаемым значением добавляется к восстановленному открытому тексту (но не удаляется после расшифровки). Открытый текст на целый блок длиннее, чем ожидалось, с предсказуемым дополнительным блоком. Ожидаемым значением всегда является количество дополненных байтов, поэтому для полного блока заполнения вы получаете 16 байтов 0x10 (16).
Например: открытый текст заканчивается на четном блоке с помощью:< /p>
Код: Выделить всё
... 0x01 0x02 0x03
Код: Выделить всё
... 0x01 0x02 0x03
Код: Выделить всё
0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10
Код: Выделить всё
0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10
Например: открытый текст заканчивается на неполном блоке с помощью:< /p>
Код: Выделить всё
0x01
Код: Выделить всё
0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01
Код: Выделить всё
0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01
Код: Выделить всё
0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10
Код: Выделить всё
0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10
Ключ – 16. байт (128 бит), а размер входного и выходного буферов как минимум на 2 блока больше, чем необходимо.
Не могу поверить, что я единственный, кто это видит, если только все не смогли это увидеть. избавиться от ECB (хотя мне нужно расшифровать уже существующие файлы).
Вот шифрование:
Код: Выделить всё
// Encrypt data_length bytes of data into enc_data using key
EVP_CIPHER_CTX* ctx{EVP_CIPHER_CTX_new()};
if ( !ctx ) {
return -1;
}
EVP_CIPHER* cipher{EVP_CIPHER_fetch(nullptr, "AES-128-ECB", nullptr)};
if ( !cipher ) {
return -1;
}
// Explicitly enable padding - doesn't seem to matter
int padding{1};
OSSL_PARAM params[2];
params[0] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_PADDING,&padding);
params[0] = OSSL_PARAM_construct_end();
if ( EVP_EncryptInit_ex2(ctx,cipher,key,nullptr,params) != 1 ) {
return -1;
}
int input_ptr{0};
int output_ptr{0};
// Encrypt until the output_ptr meets or exceeds the input data_length
while ( output_ptr < data_length ) {
int this_enc_len{0};
if ( EVP_EncryptUpdate(ctx,reinterpret_cast(enc_data) + output_ptr,&this_enc_len,reinterpret_cast(data) + input_ptr, data_length - input_ptr) != 1 ) {
return -1;
}
input_ptr += this_enc_len;
output_ptr += this_enc_len;
}
int final_enc_len{0};
if ( EVP_EncryptFinal_ex(ctx,reintrepret_cast(enc_data) + output_ptr,&final_enc_len) != 1 ) {
return -1;
}
output_ptr += final_enc_len;
// Cleanup omitted for brevity
return output_ptr;
Расшифровка аналогична:
Код: Выделить всё
// Decrypt data_length bytes of data into dec_data using key
EVP_CIPHER_CTX* ctx{EVP_CIPHER_CTX_new()};
if ( !ctx ) {
return -1;
}
EVP_CIPHER* cipher{EVP_CIPHER_fetch(nullptr, "AES-128-ECB", nullptr)};
if ( !cipher ) {
return -1;
}
// Explicitly enable padding - doesn't seem to matter here either
int padding{1};
OSSL_PARAM params[2];
params[0] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_PADDING,&padding);
params[0] = OSSL_PARAM_construct_end();
if ( EVP_DecryptInit_ex2(ctx,cipher,key,nullptr,params) != 1 ) {
return -1;
}
int input_ptr{0};
int output_ptr{0};
while ( output_ptr < data_length ) {
int this_enc_len{0};
if ( EVP_DecryptUpdate(ctx,reinterpret_cast(dec_data) + output_ptr,&this_enc_len,reinterpret_cast(data) + input_ptr, data_length - input_ptr) != 1 ) {
return -1;
}
input_ptr += this_enc_len;
output_ptr += this_enc_len;
}
int final_enc_len{0};
if ( EVP_DecryptFinal_ex(ctx,reinterpret_cast(dec_data) + output_ptr,&final_enc_len) != 1 ) {
return -1;
}
output_ptr += final_enc_len;
// Cleanup again omitted for brevity
return output_ptr;
Подробнее здесь: https://stackoverflow.com/questions/785 ... nssl-1-0-2