2015-09-11 3 views
1

Итак, у меня есть 5 файлов, которые я шифрую. Я не устанавливаю IV.Файлы полностью не дешифруются, режим AES CBC. Первый блок не decrpyted. WCAPI

отлично кулак файл дешифровать, в

то первый блок из оставшихся файлов не расшифрован.

Таким образом, файлы расшифровываются на 99%.


Ive попытался установить IV в статическое значение и случайное значение, то же самое.

Первый файл, который я шифрую, НЕ должен быть первым файлом, который я дешифрую, чтобы он был на 100% расшифрован.

Что побуждает меня думать, что оно связано с расшифровкой?


Так что для шифрования я импортирую ключ aes для создания ключевого дескриптора.

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

Если у меня есть новый ключ ручки для каждого файла ..?

Есть ли функция для очистки ключа?

Что-то говорит мне, что WCAPI использует последний блок последнего файла в качестве IV для следующего файла?

простите меня, если я могу что-то недопонимать.

Вот функция decrypt_file:

DWORD dwMode = CRYPT_MODE_CBC; 

LPVOID aes_key = NULL; 
LPVOID tmp_blk_buff = NULL; 
DWORD bytes_read = NULL; 

BOOL eof = FALSE; 

DWORD tmp_blk_buff_size = TMP_BLOCK_BUFFER_SIZE(context->in_size); 

tmp_blk_buff = VirtualAlloc(0, tmp_blk_buff_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 

Utils::zero_mem(tmp_blk_buff, tmp_blk_buff_size); 

LPVOID iv_ = NULL; 
iv_ = VirtualAlloc(0, AES_BLOCK_SIZE_, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 
Utils::zero_mem(iv_, AES_BLOCK_SIZE_); 

/*BYTE iv[AES_BLOCK_SIZE_] = { 
    0xAD, 0xAD, 0xAD, 0xAD, 
    0xAD, 0xAD, 0xAD, 0xAD, 
    0xAD, 0xAD, 0xAD, 0xAD, 
    0xAD, 0xAD, 0xAD, 0xAD 
}; 
*/ 
// Utils::copy_mem(iv_, AES_BLOCK_SIZE_, iv, AES_BLOCK_SIZE_); 


//CryptSetKeyParam(context->aes_hKey, KP_IV, (BYTE*)&iv_, 0); 

CryptSetKeyParam(context->aes_hKey, KP_MODE, (BYTE*)&dwMode, 0); 

// Encrypt data 
do{ 
    Utils::zero_mem(tmp_blk_buff, tmp_blk_buff_size); 
    bytes_read = NULL; 

    ReadFile(hFile_in, tmp_blk_buff, AES_BLOCK_SIZE_, &bytes_read, NULL); 

    if (bytes_read < AES_BLOCK_SIZE_) 
    { 
     eof = TRUE; 
    } 

    if (!CryptDecrypt(context->aes_hKey, NULL, eof, 0,(LPBYTE)tmp_blk_buff, &bytes_read)) 
    { 
     context->last_error = GetLastError(); 

     eof = TRUE; 
    } 

    WriteFile(hFile_out, tmp_blk_buff, bytes_read, &bytes_read, NULL); 

} while (!eof); 

// =============== 
// Zero and Free Allocated memory. 
Utils::zero_mem(tmp_blk_buff, tmp_blk_buff_size); 
VirtualFree(tmp_blk_buff, tmp_blk_buff_size, MEM_RELEASE); 

return (DWORD)1; 
+0

Я думаю, что вы правы в этом, принося последний блок одного файла вперед к первому из следующего. Если вы все равно не устанавливаете IV, можете также указать режим ECB, имея в виду, что ECB не очень безопасен. В противном случае, если вы хотите остаться с режимом CBC, сбросьте IV ко всем 0 байтам перед расшифровкой каждого нового файла. – WDS

+0

Но просто для уточнения, CBC с IV всех 0 байтов точно такой же, как и ECB. Но это применимо только к первому блоку файла. После этого, когда цепочка срабатывает, режим CBC защитит другие блоки. – WDS

+0

@WDS Я думаю, вы знаете, что вы имеете в виду, но ваше утверждение вводит в заблуждение. Чтобы уточнить, CBC с IV всех 0 и ECB - это не одно и то же. Результат первого блока тот же, но последующие блоки вычисляются по-разному между ними. См. Https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation для изображения ЕЦБ и CBC. –

ответ

0

Я использовал CryptDuplicateKey с соответствующим вызовом DestroyKey, который решил мои проблемы.

Использование дублированного ключа для установки параметров, при сохранении неподключенного оригинального ключа.

0

Да, это говорит о том, что у вас есть IV другое на данном шифрования/дешифрования пары.

Причина, по которой только первый блок является «поврежденным», заключается в том, что ошибки блока CBC распространяются только на следующий блок (и не далее).

Вы либо цепляетесь от предыдущей операции (если вы повторно используете контекст между файлами), либо не инициализируете контекст одним и тем же значением для шифрования и дешифрования.

Глядя на ваш код, вы закомментировали CryptSetKeyParam(....,KP_IV,....), что означает, что ваш контекст AES, вероятно, имеет неизвестные данные в IV.

Общепринятая практика всегда использует 0 для IV, но в начале данных помещает блок случайной «соли». Затем вы игнорируете первый блок данных при расшифровке. Это только случайное распределение данных.

ИЛИ, вы можете рандомизировать IV, но отправить его в виде простого текста в зашифрованное сообщение. Это также очень распространено.

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

Это почти такой же результат (в итоге вы передаете 16 байтов в качестве служебных), но вы должны поместить некоторую случайность в свое сообщение (либо через IV, либо в первый блок), чтобы помешать атакам коротких сокращений.