Ключевое слово в защите информации
ключевое слово
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline jonik  
#1 Оставлено : 29 января 2013 г. 10:48:01(UTC)
jonik

Статус: Новичок

Группы: Участники
Зарегистрирован: 18.01.2013(UTC)
Сообщений: 4

Как сделать с помощью контейнера и ключей присоединенную ЭЦП.
Вот как создаю подпись, делал по примеру из help.
Код:

procedure SignFile1(const ASourceFile, ADestFile: string);
var
  Prov: HCRYPTPROV;
  Hash: HCRYPTHASH;
  hKey: HCRYPTKEY;
  Param: CRYPT_PIN_PARAM;
  PassStr, AContainerName: string;
  Source, Dest: TMemoryStream;
  Buffer, Signature: Pointer;
  cbHash, SourceBufLen, DestBufLen, dwBlobLen: DWORD;
  pbKeyBlob, pbHash: PBYTe;
begin
  AContainerName := 'test';
  Win32Check(CryptAcquireContext(@Prov, PChar(AContainerName),
    PChar(CP_GR3410_2001_PROV_A),
    PROV_GOST_2001_DH, 0 {CRYPT_SILENT}));
  PassStr := '111';
// Установка параметров в соответствии с паролем.
  if not CryptSetProvParam(Prov, PP_KEYEXCHANGE_PIN, @passStr[1], 0) then
    ShowMessage('CryptSetProvParam' + IntToStr(GetLastError));
// Получение ключа пользователя.
    if CryptGetUserKey(Prov, AT_KEYEXCHANGE, @hKey) then
      ShowMessage('CryptGetUserKey succeeded.');
    // Экпорт открытого ключа. 
    if CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, nil, dwBlobLen) then
        ShowMessage('Size of the BLOB for the public key determined.');
    // Распределение памяти под pbKeyBlob.
    GetMem(pbKeyBlob, dwBlobLen);
    // Сам экспорт в ключевой BLOB.
    if CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, Pointer(pbKeyBlob), dwBlobLen) then
      ShowMessage('Contents have been written to the BLOB.');
 // Создание объекта функции хеширования.
  try
    Win32Check(CryptCreateHash(Prov, CALG_GR3411, 0, 0, @Hash));
  except
    on E: Exception do
      ShowMessage('CryptCreateHash ' + E.Message);
  end;

  // Передача параметра HP_OID объекта функции хеширования.
  // Определение размера BLOBа и распределение памяти.
  if CryptGetHashParam(Hash, HP_OID, nil, cbHash, 0) then
    ShowMessage('Size of the BLOB determined.');

  GetMem(pbHash, cbHash);
  // Копирование параметра HP_OID в pbHash.
  if CryptGetHashParam(Hash, HP_OID, Pointer(pbHash), &cbHash,0) then
    ShowMessage('Parameters have been written to the pbHash.');

  // Вычисление криптографического хеша буфера.
  Source := TMemoryStream.Create;
  try
    Source.LoadFromFile(ASourceFile);
      try
        Win32Check(CryptHashData(Hash, Source.Memory, Source.Size, 0))
      except
        on E: Exception do
          ShowMessage('CryptHashData ' + E.Message);
      end;
  finally
    Source.Free;
  end;
  // Определяем длину
  DestBufLen := 0;
  try
    Win32Check(CryptSignHash(hash, AT_KEYEXCHANGE, nil, 0, nil, DestBufLen));
  except
    on E: Exception do
      ShowMessage('CryptSignHash 1' + E.Message);
  end;
  if DestBufLen > 0 then
  begin
  // Распределение памяти под буфер подписи.
    GetMem(Signature, DestBufLen);
    try
      Win32Check(CryptSignHash(hash, AT_KEYEXCHANGE, nil, 0, signature, DestBufLen));
    except
      on E: Exception do
        ShowMessage('CryptSignHash 1' + E.Message);
    end;
    try
      Dest := TMemoryStream.Create;
      Dest.Position := 0;
      Dest.WriteBuffer(Signature^, DestBufLen);
      dest.SaveToFile(ADestFile);
    finally
      Dest.Free;
    end;
  end;
  //--- Запись результата в поток
  CryptDestroyHash(Hash);
  CryptReleaseContext(Prov, 0);
end;
end;

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

Отредактировано пользователем 29 января 2013 г. 10:57:32(UTC)  | Причина: Не указана

Вложение(я):
test.txt (4kb) загружен 38 раз(а).

У Вас нет прав для просмотра или загрузки вложений. Попробуйте зарегистрироваться.
Offline jonik  
#2 Оставлено : 29 января 2013 г. 15:21:21(UTC)
jonik

Статус: Новичок

Группы: Участники
Зарегистрирован: 18.01.2013(UTC)
Сообщений: 4

Насколько я понял, поискав на форуме. Использую CryptSignHash, я не смогу подписать файл в виде PKCS#7, правильно я понял?
Чтобы мне подписать документ в формате PKCS7, нужно использовать CryptSignMessage и сертификаты?
Offline Kirill Sobolev  
#3 Оставлено : 29 января 2013 г. 16:41:31(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,733
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Цитата:
Использую CryptSignHash, я не смогу подписать файл в виде PKCS#7, правильно я понял?

Правильно
Цитата:
Чтобы мне подписать документ в формате PKCS7, нужно использовать CryptSignMessage и сертификаты?

Да.
Если важно использование ключей, то посмотрите CryptSignMessageWithKey.
Техническую поддержку оказываем тут
Наша база знаний
Offline Юрий  
#4 Оставлено : 30 января 2013 г. 9:32:24(UTC)
Юрий

Статус: Активный участник

Группы: Участники
Зарегистрирован: 22.01.2008(UTC)
Сообщений: 675
Мужчина
Российская Федерация
Откуда: Йошкар-Ола

Сказал «Спасибо»: 3 раз
Поблагодарили: 95 раз в 68 постах
Кирилл немного упростил. На самом деле очень даже возможно создать сообщение в формате PKCS#7 используя CryptSignHash. Вот только надо потом правильно "собрать" PKCS#7 сообщение используя CryptEncodeObject.
Если интересно можете "покопать" и в эту сторону.
С уважением,
Юрий Строжевский
Offline jonik  
#5 Оставлено : 30 января 2013 г. 12:44:03(UTC)
jonik

Статус: Новичок

Группы: Участники
Зарегистрирован: 18.01.2013(UTC)
Сообщений: 4

Автор: Юрий Перейти к цитате
Кирилл немного упростил. На самом деле очень даже возможно создать сообщение в формате PKCS#7 используя CryptSignHash. Вот только надо потом правильно "собрать" PKCS#7 сообщение используя CryptEncodeObject.
Если интересно можете "покопать" и в эту сторону.

Если не трудно можете дать пинок в нужном направлении, пока я себе слабо представляю?

И еще пару вопросов. У меня используется флэшка с PIN кодом.
Silent режим, мне UI не нужен
Если пароль не верный, то выскакивает окно с предложением ввести пароль, как можно получить ошибку, что пароль не верный, а не окно?

Как проверить установлен в контейнере PIN или нет?

Offline Юрий  
#6 Оставлено : 3 февраля 2013 г. 18:00:43(UTC)
Юрий

Статус: Активный участник

Группы: Участники
Зарегистрирован: 22.01.2008(UTC)
Сообщений: 675
Мужчина
Российская Федерация
Откуда: Йошкар-Ола

Сказал «Спасибо»: 3 раз
Поблагодарили: 95 раз в 68 постах
"Пинок" простой - искать примеры с встречающимся использованием CryptEncodeObject и почитать документацию на MSDN по этой функции.
Про PIN - ищите на этом форуме, этот вопрос возникает здесь регулярно.
С уважением,
Юрий Строжевский
Offline jonik  
#7 Оставлено : 4 февраля 2013 г. 11:31:44(UTC)
jonik

Статус: Новичок

Группы: Участники
Зарегистрирован: 18.01.2013(UTC)
Сообщений: 4

Про PIN - все работает нормально, я тестировал в GUI приложении, поэтому окно и вылетало, проверил в качестве сервиса - ошибки выдает, все как и положено.
По поводу CryptEncodeObject пока отложу на потом, для собственного развития, тема интересная, но требует много времени.

Отредактировано пользователем 4 февраля 2013 г. 11:32:34(UTC)  | Причина: Не указана

RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.