| ||||
| ||||
Насколько я понял, для того , чтобы подписать файл, необходимо полностью загрузить его в память (либо отмаппировать). А если размер файла - несклько десятков мегабайт (если не сотен) (например хочу свернуть директории рекурсивно)? В Вербе были функции - отдельно функция подписи блока памяти, отдельно функция подписи файла. Здесь такого нет? И вообще как влияет размер подписываемых данных на достоверность ЭЦП? | ||||
Ответы: | ||||
| ||||
Ну не совсем так. Если посмотрите MSDN, то существует 3 возможности подписать файл: 1. Используя базовые функции, где подписывается хэш, и соответственно размер файла не имеет занчения, так как хеш накапливается. 2. Функция CryptSignMessage из Simplified message. Там действительно подписывается кусок памяти. 3. Функция (вернее последовательность выполнения нескольких) CryptMsgUpdate, где логика работы как в хэше BOOL WINAPI CryptMsgUpdate( HCRYPTMSG hCryptMsg, const BYTE *pbData, DWORD cbData, BOOL fFinal ); и есть флаг fFinal. А вот как в Вербе подписать одной подписью все файлы в директории я не знаю. | ||||
| ||||
Я использую для подписи файла базовые функции CPHashData CPSignData Я правильно понял, что при этом хэш накапливается? Т.е. я один раз создал дескриптор хэша CPCreateHash а потом поблочно читаю файл, каждый блок загоняю в этот дескриптор хэша функцией CPHashData (т.е. эта функция вызывается для одного дескриптора хэша столько раз сколько блоков данных в файле), а затем один раз вызываю CPSignData, подписывая данный дескриптор хэша. Это верная форма подписи большого файла? А то у вас в примере для использования базовых функций ctkey.c подписываемый файл целиком засасывается в память. И еще вопрос - длина подписи постоянна - 64 байта? | ||||
| ||||
Точно так и делается. А в примере просто для наглядности так сделано. | ||||
| ||||
Нет необходимости загружать весь файл в память при его шифровании и хешировании. Функции шифрования и хеширования - потоковые, поэтому достаточно открыть файл, читать его фрагментарно, обрабатывать фрагменты функциями шифрования и хеширования. Признак конца файла передаётся через параметр Finel, закрывающий поток шифрования и хеширования. Вот простой пример: /* Open source file.*/ if((hSource=fopen(SourceFullPath,"rb"))==NULL) { printf("Error opening source file!\n"); return FALSE; } /* Open destination file.*/ if((hDst=fopen(EncryptFileFullPath,"wb+"))==NULL) { printf("Error opening destination file!\n"); return FALSE; } /* Encrypt source file and write to destination file.*/ do { /* Read up to BLOCK_SIZE bytes from source file.*/ dwCount = fread(pbBuffer, 1, BUFFER_SIZE, hSource); if(ferror(hSource)) { printf("Error reading data!\n"); return FALSE; } eof=feof(hSource); if(!CPHashData(hContainer, hFileSignHash, pbBuffer, dwCount, 0)) { printf("Error %x during CPHashData!\n", GetLastError()); return FALSE; } if(!CPEncrypt(hContainer,hEncryptKey, hFileHash, eof, 0, pbBuffer, &dwCount, BUFFER_SIZE)) { printf("Error %x during CryptEncrypt!\n", GetLastError()); return FALSE; } fwrite(pbBuffer, 1, dwCount, hDst); if(ferror(hDst)) { printf("Error writing data!\n"); return FALSE; } } while(!feof(hSource)); if(hSource != NULL) fclose(hSource); if(hHeader != NULL) fclose(hHeader); | ||||