Статус: Новичок
Группы: Участники
Зарегистрирован: 10.03.2009(UTC) Сообщений: 2 Откуда: home
|
Добрый день! При шифровании и расшифровки файлов большого размера (>100mb) использую поточное шифрование/расшифрование. Шифрование идет на ура. Расшифровка же делается очень долго. Вот кусок кода, реализующий расшифровку и запись в файл... Код:
BOOL
WINAPI
DecodeCallback(
const void *pvArg,
BYTE *pbData,
DWORD cbData,
BOOL fFinal)
{
DWORD dwWrittenBytes = -1;
HANDLE hFileToWrite = INVALID_HANDLE_VALUE;
hFileToWrite = (HANDLE)pvArg;
if ( !WriteFile(
hFileToWrite,
pbData,
cbData,
&dwWrittenBytes,
NULL) ||
(dwWrittenBytes != cbData))
{
DWORD result = GetLastError();
return E_FAIL;
}
return TRUE;
}
STDMETHODIMP CDecrypt::DecodeContext()
{
CMSG_CTRL_DECRYPT_PARA decryptPara;
memset(&decryptPara, 0, sizeof(CMSG_CTRL_DECRYPT_PARA));
decryptPara.dwRecipientIndex = (DWORD)-1;
decryptPara.cbSize = sizeof(CMSG_CTRL_DECRYPT_PARA);
decryptPara.dwKeySpec = AT_KEYEXCHANGE;
// Fill the CMSG_STREAM_INFO structure.
CMSG_STREAM_INFO stStreamInfo2;
// BER_ENCODING
stStreamInfo2.cbContent = 0xffffffff;
stStreamInfo2.pfnStreamOutput = DecodeCallback;
//Открываем файл на запись
HANDLE hOutMsgFile = INVALID_HANDLE_VALUE;
hOutMsgFile = CreateFileA(
CODED_FILE_NAME,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hOutMsgFile == INVALID_HANDLE_VALUE)
{
CCommon::ProccessError(GetLastError(), &errorInfo);
CCommon::SetError(errorInfo.error, errorInfo.stringError);
return E_FAIL;
}
//Открываем файл на чтение
HANDLE hInMsgFile = INVALID_HANDLE_VALUE;
hInMsgFile = CreateFileA(
ENCODED_FILE_NAME,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == hInMsgFile)
{
CCommon::ProccessError(GetLastError(), &errorInfo);
CCommon::SetError(errorInfo.error, errorInfo.stringError);
return E_FAIL;
}
stStreamInfo2.pvArg = hOutMsgFile;
//Получаем указатель на message
if(!(hMsg = CryptMsgOpenToDecode(
TYPE_DER, // encoding type
0, // flags
0, // message type (get from message)
NULL, // cryptographic provider
// use NULL for the default provider
NULL, // recipient information
&stStreamInfo2))) // stream information
{
CCommon::ProccessError(GetLastError(), &errorInfo);
CCommon::SetError(errorInfo.error, errorInfo.stringError);
return E_FAIL;
}
//Читаем зашифрованный файл
contextLength = 256; //От изменения размера кусков время обработки не меняет
context = new BYTE[contextLength];
DWORD cbBytesRead;
BOOL lastCall = FALSE;
while (ReadFile(
hInMsgFile,
context,
contextLength,
&cbBytesRead,
NULL))
{
if (cbBytesRead < contextLength)
{
lastCall = TRUE;
}
if(!(CryptMsgUpdate(
hMsg, // handle to the message
context, // pointer to the encoded BLOB
cbBytesRead, // size of the encoded BLOB
lastCall))) // last call //Вот тут самые большие временные затраты
{
CCommon::ProccessError(GetLastError(), &errorInfo);
CCommon::SetError(errorInfo.error, errorInfo.stringError);
return E_FAIL;
}
if (lastCall)
{
break;
}
}
CloseHandle(hInMsgFile);
/*Далее идет Работа с сертификатом - проходит нормально*/
//Получаем результат шифрования и пишем в файл (вызов DecodeCallbak)
if (!CryptMsgControl(
hMsg,
0,
CMSG_CTRL_DECRYPT,
&decryptPara))
{
CCommon::ProccessError(GetLastError(), &errorInfo);
CCommon::SetError(errorInfo.error, errorInfo.stringError);
return E_FAIL;
}
//Чистим за собой
CryptMsgClose(hMsg);
CloseHandle(hOutMsgFile);
return S_OK;
}
Надеюсь на помощь...
|