| 
	Статус: Участник
 Группы: Участники
Зарегистрирован: 20.07.2021(UTC)
 Сообщений: 13
 
 Сказал(а) «Спасибо»: 6 раз
 | 
            
		      
                Автор: Андрей *  Автор: tonax  Автор: Андрей *  Автор: tonax  Автор: Андрей *  На тестовой странице присоединенная подпись формируется. В чем ещё отличие?  Разные результаты подписания строки, например KZEKPLILATPSQLIFKVVYILQFEPIZAW Вот первая строка программное полученной подписанной строки:  MIIfHwYJKoZIhvcNAQcCoIIfEDCCHwwCAQExDjAMBggqhQMHAQECAgUAMAsGCSqGSIb3DQEHAaCC А вот правильная с https://www.cryptopro.ru.../cades_bes_sample.html#:  MIIfbQYJKoZIhvcNAQcCoIIfXjCCH1oCAQExDjAMBggqhQMHAQECAgUAMC0GCSqGSIb3DQEHAaAg  и так в каждой строчке какие-то отличия Разные типы CMS, разный размер структур => разный base64 + в конце всегда будет разное значение ЭП.  Дело в том, что честный знак не принимают программную подпись, а с https://www.cryptopro.ru...ge/cades_bes_sample.html  прекрасно принимает... Видимо что-то все-таки неправильно формируется ч-з function SignData(), только не могу понять что. Base64 верная, проверял в https://helpers.work/ru/encription/base64 Еще раз. Ответ выше был дан. На тестовой странице - присоединенная подпись. В коде на Delphi\Lazarus: SignData(True , si, so, null, '');  - что делает этот вызов? Не могу понять ход мысли :) На тестовой странице https://www.cryptopro.ru...ge/cades_bes_sample.html  мы используем подпись и результат получается верный. Если мы пытаемся выполнить подпись аналогичной строки, той же самой подписью, что и используется для проверки подписи на тестовой странице, но из программы Delphi, то получаем другой (неверный) результат SignData(True , si, so, null, ''); как раз выполняет вызов функции подписи строки si и возвращает результат в so. null указывали, до того, как смогли получить сертификат.Сейчас весь год выглядит так: Код:
//Поиск сертификата по отпечатку
function GetCertificateOfStamp(thumbprint: string; var oCertificate: olevariant; var onErr: string): boolean;
const
  CAPICOM_MY_STORE = 'MY';
  CAPICOM_CERTIFICATE_FIND_SHA1_HASH = $00000000;
  CAPICOM_CURRENT_USER_STORE = 2;
  CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2;
var
  oStore, oCertificates: olevariant;
  x: integer;
begin
  onErr := '';
  result := false;
  try
    oStore := CreateOleObject('CAdESCOM.Store');
    oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
    oCertificates := oStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, widestring(thumbprint));
    x := oCertificates.Count;
    if x = 0 then
    begin
      onErr := 'Не найден сертификат с отпечатком: [' + thumbprint + ']';
      exit;
    end;
    oCertificate := oCertificates.Item[1]; // oCertificates.Item(1);
    result := true;
  except
    on e: exception do
    begin
      onErr := 'Не удалось получить доступ к сертификату с отпечатком: [' + thumbprint + '] ' + e.Message;
    end;
  end;
end;
 Поиск проходит успешно, т.к. по отпечатку после поиска получаем верный серийный номер Ниже идет основная функция подписания, в параметры которой передаются True(bl_Detached), строка для подписания, ссылка на переменную для подписанной строки, Сертификат и его пароль. А на что влияет первый параметр bl_Detached ? Код:
//Функция подписания строки
function SignData(bl_Detached: boolean; S_in: WideString; var S_out: WideString ; g_Cert:OleVariant; g_Cert_Pass:string) :boolean;
const
  CADESCOM_CADES_TYPE = 1; // Тип усовершенствованной подписи
  CADESCOM_BASE64_TO_BINARY = 1;
var
  v_Signer, v_SignedData : Variant;
  s, Encoded: string;
  Base64: TBase64Encoding;
begin
  Result := False;
  try
    v_Signer := CreateOLEObject('CadesCOM.CPSigner');
    v_Signer.Certificate := g_Cert;
    //v_Signer.Certificate := GetSignerCertificate('0171ed4800daab20a54de41e513396cbae');
    if g_Cert_Pass<>'' then
    v_Signer.KeyPin := g_Cert_Pass;
    v_Signer.Options := 1;// CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN := 1;
    V_SignedData := CreateOLEObject('CAdESCOM.CadesSignedData');
    v_SignedData.ContentEncoding := CADESCOM_BASE64_TO_BINARY;
    Base64 := TBase64Encoding.Create(0);
  //s := 'Some larger text that needs to be encoded in Base64 encoding';
  //Base64 := TBase64Encoding.Create(10, '');
    s_in := Base64.Encode(s_in);
    //s_in := EncodeStringBase64(s_in);
    v_SignedData.Content := s_in;
    s_out := v_SignedData.SignCades(v_Signer, CADESCOM_CADES_TYPE, bl_Detached, 0);
    Result := True;
  finally
    if not VarIsNull(v_Signer) then v_Signer := Unassigned;
    if not VarIsNull(v_SignedData) then v_SignedData := Unassigned;
  end;
end;
 Затем вызов: Сначала ищем сертификат по отпечатку, после чего выполняем подписание строки Код:
procedure TForm1.btn1Click(Sender: TObject);
const
  certStamp = 'тут указываем отпечаток сертификата';
var
  si,so: WideString;
  Cert: OleVariant;
  errStr: string;
  crtRes: boolean;
begin
  si := edtString.Text; //Строка для подписания
  crtRes := GetCertificateOfStamp(certStamp, Cert, errStr); //поиск по сертификату
  if not crtRes then //Если сертификат не найден
    begin
      ShowMessage(errStr);
      exit;
    end;
  ShowMessage('Серийный номер: ' + Cert.SerialNumber); //Печатаем серийный номер найденного по отпечатку сертификата
  SignData(True, si, so, Cert, ''); //Подписываем строку si сертификатом Cert, пароль не указываем, т.к. его нет
  mmo1.Text := so; //Результат подписания выводим по поле формы
end;
 |