06.12.2001 10:22:33ЭЦП Ответов: 4
Сергей
Насколько я понял, для того , чтобы подписать файл, необходимо полностью загрузить его в память (либо отмаппировать). А если размер файла - несклько десятков мегабайт (если не сотен) (например хочу свернуть директории рекурсивно)?
В Вербе были функции - отдельно функция подписи блока памяти, отдельно функция подписи файла.
Здесь такого нет?
И вообще как влияет размер подписываемых данных на достоверность ЭЦП?
 
Ответы:
06.12.2001 13:34:44kure
Ну не совсем так.
Если посмотрите MSDN, то существует 3 возможности подписать файл:
1. Используя базовые функции, где подписывается хэш, и соответственно размер файла не имеет занчения, так как хеш накапливается.
2. Функция CryptSignMessage из Simplified message. Там действительно подписывается кусок памяти.
3. Функция (вернее последовательность выполнения нескольких) CryptMsgUpdate, где логика работы как в хэше
BOOL WINAPI CryptMsgUpdate(
HCRYPTMSG hCryptMsg,
const BYTE *pbData,
DWORD cbData,
BOOL fFinal
);
и есть флаг fFinal.
А вот как в Вербе подписать одной подписью все файлы в директории я не знаю.
06.12.2001 16:22:50Сергей
Я использую для подписи файла базовые функции
CPHashData
CPSignData
Я правильно понял, что при этом хэш накапливается?
Т.е. я один раз создал дескриптор хэша CPCreateHash
а потом поблочно читаю файл, каждый блок загоняю
в этот дескриптор хэша функцией CPHashData
(т.е. эта функция вызывается для одного дескриптора хэша столько раз сколько блоков данных в файле), а затем один раз вызываю
CPSignData, подписывая данный дескриптор хэша.
Это верная форма подписи большого файла?
А то у вас в примере для использования базовых функций ctkey.c подписываемый файл целиком засасывается в память.
И еще вопрос - длина подписи постоянна - 64 байта?


06.12.2001 17:09:09kure
Точно так и делается.
А в примере просто для наглядности так сделано.
29.12.2001 17:24:10RealName
Нет необходимости загружать весь файл в память при его шифровании и хешировании.
Функции шифрования и хеширования - потоковые, поэтому достаточно открыть файл, читать его фрагментарно, обрабатывать фрагменты функциями шифрования и хеширования. Признак конца файла передаётся через параметр 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);