winapi — CryptDecrypt () Не удается расшифровать некоторые блоки Переполнение стека

В настоящее время я работаю над простой системой шифрования / дешифрования в C ++ с использованием Windows API.

Я считаю, что мне удалось получить CryptEncrypt() работать (AES_128) для шифрования файла.
Но когда я использую CryptDecrypt() чтобы расшифровать файл, первые 16 байтов повреждаются, а затем после 4000 байтов (это размер фрагментов, которые я извлекаю из ReadFile() и шифрование) это еще один кусок поврежденных байтов и так далее. Если я пытаюсь расшифровать файл с общей длиной менее 4000 байт, расшифровка работает отлично.

Я очень смущен тем, почему это происходит. Там нет ошибок вообще.

Вот фрагмент моего кода (у меня есть CryptEncrypt() а также CryptDecrypt() сразу за другим, чтобы сэкономить на экспорте ключа и ускорить тестирование):

DWORD bytesRead;
DWORD bytesWritten;
DWORD pointer = 0;
unsigned int blockSize = 4000;
void *fileBuffer = new unsigned char[4106];
bool EOF = false;
do
{
SetFilePointer(hFileOrginal,pointer,0,0);
ReadFile(hFileOrginal,fileBuffer,blockSize,&bytesRead,NULL);
if(bytesRead<blockSize)
{
EOF=true;
}
CryptEncrypt(aesKey,NULL,EOF,0,(BYTE *)fileBuffer,&bytesRead,(blockSize+16));
CryptDecrypt(aesKey,NULL,EOF,0,(BYTE *)fileBuffer,&bytesRead);

WriteFile(hTempFile,fileBuffer,bytesRead,&bytesWritten,NULL);
pointer +=bytesRead;
}
while(!EOF);
delete[] fileBuffer;

Буду очень признателен за любые предложения о том, что происходит не так.

РЕДАКТИРОВАТЬ: В файле 4704 байтов я получил следующее с использованием точек останова.

Первый ReadFile bytesread 4000
Первый CryptEncrypt bytesRead 4000
Первый CryptDecrypt bytesRead 4000
Второй ReadFile bytesread 704
Второй CryptEncrypt bytesread 720
Second CryptDecrupt bytesread 704

Все, кажется, хорошо с этим, но у меня все еще есть проблема.

Я использую расширенный crypto api (с verifycontext) с сгенерированным одиночным ключом AES со свойством CRYPT_EXPORTABLE

0

Решение

Вы вообще не обрабатываете ошибки. Все функции API, которые вы вызываете, имеют возвращаемые значения и коды ошибок, ни одну из которых вы не проверяете.

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

Попробуйте что-то более похожее на это:

bool ReadFromFile(HANDLE hFile, void *Buffer, DWORD BufSize, DWORD *BytesRead)
{
if (BytesRead)
*BytesRead = 0;

LPBYTE pBuffer = (LPBYTE) Buffer;
DWORD dwRead;

while (BufSize > 0)
{
if (!ReadFile(hFile, pBuffer, BufSize, &dwRead, NULL))
return false;

if (dwRead == 0)
break;

pBuffer += dwRead;
BufSize -= dwRead;

if (BytesRead)
*BytesRead += dwRead;
}

return true;
}

bool WriteToFile(HANDLE hFile, void *Buffer, DWORD BufSize)
{
LPBYTE pBuffer = (LPBYTE) Buffer;
DWORD dwWritten;

while (BufSize > 0)
{
if (!WriteFile(hFile, pBuffer, BufSize, &dwWritten, NULL))
return false;

pBuffer += dwWritten;
BufSize -= dwWritten;
}

return true;
}

DWORD bytesRead;
const UINT blockSize = 4000;
LPBYTE fileBuffer = new BYTE[blockSize+16];
bool EOF;

if (SetFilePointer(hFileOrginal, 0, NULL, FILE_BEGIN) != 0)
{
errorCode = GetLastError();
...
}
else
{
do
{
if (!ReadFromFile(hFileOrginal, fileBuffer, blockSize, &bytesRead))
{
errorCode = GetLastError();
...
break;
}

EOF = (bytesRead < blockSize);

bytesEncrypted = bytesRead;
if (!CryptEncrypt(aesKey, NULL, EOF, 0, fileBuffer, &bytesEncrypted, blockSize+16))
{
errorCode = GetLastError();
...
break;
}

bytesDecrypted = bytesEncrypted;
if (!CryptDecrypt(aesKey, NULL, EOF, 0, fileBuffer, &bytesDecrypted))
{
errorCode = GetLastError();
...
break;
}

if (!WriteToFile(hTempFile, fileBuffer, bytesDecrypted))
{
errorCode = GetLastError();
...
break;
}

if (bytesDecrypted != bytesRead)
{
...
break;
}
}
while (!EOF);
}
delete[] fileBuffer;
3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector