logo Обзор КриптоПро NGate для защищённого доступа к корпоративным ресурсам
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Андрей Т.  
#1 Оставлено : 5 ноября 2019 г. 6:58:00(UTC)
Андрей Т.

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

Группы: Участники
Зарегистрирован: 11.02.2019(UTC)
Сообщений: 8
Российская Федерация
Откуда: Новосибирск

Здравствуйте, уважаемые эксперты.

Подписываю данные в Дельфи-2006. Я в данной теме новичок и получается все не сразу.
Написал текст процедуры для создания подписи. Процедура создает подпись, все функции выполняются без ошибок.
Проверка подписи онлайн на сайте возвращает

Цитата:

Ошибка при проверке электронной подписи:
Подлинность документа не подтверждена (HashValidationException)

Информация о документе:
ХЭШ-значение документа в формате base64: ojNytyvCrk2CsnT0QhkjtB+11za7rT+1MBVKV1n19WY=
Алгоритм ГОСТ Р 34.10-2001, используемый при экспорте/импорте ключей (OID:1.2.643.2.2.9)
Информация о сертификате:
Владелец: CN=...
Издатель: ...
Выдан: 27.12.2018 12:50:53
Действителен до: 27.12.2019 13:00:53
Алгоритм ключа: 1.2.643.2.2.3


Текст процедуры.

Код:

uses JwaWinCrypt;

type
  TSessionQuery = record
	Data: string;           // Исходные данные
    Data64: string;         // Исходные данные в Base64
    SignSize: Cardinal;
    Sign: PChar;            // Подпись в двоичном формате
    Sign64: string;         // подпись в Base64
  end;

  TProperCertificate = record
    pCert: PCERT_CONTEXT;
    hProv: HCRYPTPROV;
  end;

procedure SignData(Cert: TProperCertificate; var SessionQuery: TSessionQuery);
var
  SignPara: CRYPT_SIGN_MESSAGE_PARA;
  Error, DataSize: DWORD;
  pbArray, cbArray, pbCert: Pointer;
  pData: array[0..0] of Pointer;
  pSize: array[0..0] of DWORD;
  pCert: array[0..0] of PCERT_CONTEXT;
  S: string;
begin
  DataSize := Length(SessionQuery.Data);
  pData[0] := @SessionQuery.Data;
  pSize[0] := DataSize;
  pCert[0] := Cert.pCert;

  pbArray   := @pData[0];
  cbArray   := @pSize[0];
  pbCert    := @pCert[0];

  ZeroMemory(@SignPara, SizeOf(CRYPT_SIGN_MESSAGE_PARA));
  with SignPara do
  begin
    cbSize := SizeOf(CRYPT_SIGN_MESSAGE_PARA);
    dwMsgEncodingType := X509_ASN_ENCODING or PKCS_7_ASN_ENCODING;
    pSigningCert := Cert.pCert;
    HashAlgorithm.pszObjId := '1.2.643.2.2.9';  //  GOST R 34.11-94
    HashAlgorithm.Parameters.cbData := 0;
    pvHashAuxInfo := nil;
    cMsgCert := 1;
    rgpMsgCert := pbCert;
    cMsgCrl := 0;
    rgpMsgCrl := nil;
    cAuthAttr := 0;
    rgAuthAttr := nil;
    cUnauthAttr := 0;
    rgUnauthAttr := nil;
    dwFlags := 0;
    dwInnerContentType := 0;
  end;

  if not CryptSignMessage(@SignPara, False, 1, pbArray, cbArray, nil, SessionQuery.SignSize) then {...} ;
  
  GetMem(SessionQuery.Sign, SessionQuery.SignSize);

  if not CryptSignMessage(@SignPara, False, 1, pbArray, cbArray, PByte(SessionQuery.Sign), SessionQuery.SignSize) then {...} ;

  SetLength(S, SessionQuery.SignSize);
  Move(SessionQuery.Sign^, S[1], SessionQuery.SignSize);
  SessionQuery.Sign64 := EncodeString(S);
end;


Уже несколько дней пытаюсь найти ошибку, но воз и ныне там.
Что я делаю не так?
Offline two_oceans  
#2 Оставлено : 5 ноября 2019 г. 8:25:48(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 732
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 48 раз
Поблагодарили: 156 раз в 148 постах
Добрый день.
Навскидку мне не очень нравится: 1) что есть Pchar - на разных версиях компиляторов Паскаля и в разных ситуациях он обрабатывается немного по разному - когда-то как строка, когда-то как указатель. Имеет смысл когда результат - строка с символом 0 в конце, но в данном случае результат - двоичные данные, pchar не дает никаких преимуществ над pointer, а вот глюки с преобразованием к указателю возможны. лично я исправил бы на pointer.
2) с массивами что-то намудрили, но на первый взгляд ошибок не вижу. Аналогично с проставлением нулей и nil после зануления структуры в целом - смотрится странно, но верно. Синтаксические понятно уже бы вылезли, но могут быть логические вроде указателя на указатель на данные вместо указателя на данные или вроде того. Если string расширенный (длинее 255 символов), то может "прыгать" по памяти и тогда не подходит для вызовов WinApi. Имеет смысл проверить как исходный файл читается - желательно в двоичном режиме, все байты; как кодируется base64; как пишется файл после кодирования.
3) проблема проверки может быть например если указали присоединенную подпись CryptSignMessage(@SignPara, False,... , а проверить пытаетесь как отсоединенную указав 2 файла. Близко с проверкой на госзакупках не сталкивался и могу ошибаться, но обычно если подпись присоединенная, контент не заполняется, указывается только подпись (включающая в себя контент).
Offline Андрей Писарев  
#3 Оставлено : 5 ноября 2019 г. 9:14:44(UTC)
Андрей Писарев

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 8,440
Мужчина

Сказал «Спасибо»: 300 раз
Поблагодарили: 1186 раз в 929 постах
Здравствуйте.
Вместо String использовать TMemoryStream.

Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей Т.  
#4 Оставлено : 5 ноября 2019 г. 10:20:45(UTC)
Андрей Т.

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

Группы: Участники
Зарегистрирован: 11.02.2019(UTC)
Сообщений: 8
Российская Федерация
Откуда: Новосибирск

Благодарю за ответы.

Автор: two_oceans Перейти к цитате

3) проблема проверки может быть например если указали присоединенную подпись CryptSignMessage(@SignPara, False,... , а проверить пытаетесь как отсоединенную указав 2 файла. Близко с проверкой на госзакупках не сталкивался и могу ошибаться, но обычно если подпись присоединенная, контент не заполняется, указывается только подпись (включающая в себя контент).


При внимательном изучении увидел, что указанный мной сайт проверяет отсоединенную подпись. А мне по условиям задачи нужна именно присоединенная.
Не подскажите какой-либо ресурс для проверки присоединенной подписи? В гугле не находится ничего подходящего.


Хотя, впрочем, не нужно. Изменил подпись на отсоединенную, сайт выдает ошибку с тем же текстом.

Отредактировано пользователем 5 ноября 2019 г. 10:25:56(UTC)  | Причина: Не указана

Offline two_oceans  
#5 Оставлено : 5 ноября 2019 г. 13:06:59(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 732
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 48 раз
Поблагодарили: 156 раз в 148 постах
https://www.justsign.me/verifyqca/Verify/ (попробовал создать присоединенную - после ручного указания CMS формата автоматом определилось что подпись присоединенная) Экземпляров сервиса несколько, некоторые могут ругаться на тестовые сертификаты, не помню точно этот экземпляр или нет. Был вроде бы и экземпляр с тестовыми сертификатами.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.