| 
	Статус: Активный участник
 Группы: Участники
 Зарегистрирован: 30.05.2018(UTC) Сообщений: 38 Сказал(а) «Спасибо»: 7 разПоблагодарили: 2 раз в 2 постах
 
 | 
            
		      
                Задача: В Delphi подписать PDF видимой ЭЦП. Почитав мануалы, темы, написал следующее: Код:
uses OleServer, Acrobat_TLB, OleCtrls, ComObj, QStrings;
type
  PAppearance = ^TAppearance;
  TAppearance = record
    pageNumber: Integer;
    coords: array[0..3] of integer;
    appearanceFilter: string;
  end;
function BytesToHex(Value: PAnsiChar; Count: Integer): string;
var
  i: Integer;
begin
  Result := '';
  for i := 0 to Count - 1 do
  begin
    Result := Result + IntToHex(Byte(Value[i]), 2);
  end;
end;
function GetCertificate(Cert: PCCERT_CONTEXT): string;
var
  certValue: string;
begin
  SetLength(certValue, Cert.pCertInfo.SubjectPublicKeyInfo.PublicKey.cbData);
  system.Move(Cert.pCertInfo.SubjectPublicKeyInfo.PublicKey.pbData^, Pointer(certValue)^, Cert.pCertInfo.SubjectPublicKeyInfo.PublicKey.cbData);
  Result := BytesToHex(PAnsiChar(certValue), Cert.pCertInfo.SubjectPublicKeyInfo.PublicKey.cbData);
end;
procedure SignPDF;
var
  gApp: CAcroApp;
  PDDoc: CAcroPDDoc;
  AVDoc: CAcroAVDoc;
  jso: Variant;
  Appearance: PAppearance;
begin
  gApp := CoAcroApp.Create;
  gApp.Show;
  AVDoc := CoAcroAVDoc.Create;
  if AVDoc.Open('c:\1.pdf', 'c:\1.pdf') then
  begin
    PDDoc := AVDoc.GetPDDoc as CAcroPDDoc;
    jso := PDDoc.GetJSObject;
    GetMem(Appearance, SizeOf(TAppearance));
    Appearance^.pageNumber := PDDoc.GetNumPages - 1;
    Appearance^.coords[0] := 122;
    Appearance^.coords[1] := 539;
    Appearance^.coords[2] := 422;
    Appearance^.coords[3] := 122;
    Appearance^.appearanceFilter := 'Shuraken';
    jso.CPSign(GetCertificate(FMyCertificate), '', 1, 'Причина: Хотелка',
               'Местоположение: Санкт-Петербург', '', false, true, integer(Appearance));
  end;
end;
 Если ставлю предпоследний параметр в false, то подпись не создаётся. Параметр bShowSignDialogs: Флаг, указывающий будут ли отображены диалог с параметрами подписи и диалог для сохранения файла. Ставлю в true, выводится окно, где выбираю сертификат и подпись - невидимая - создаётся.  Вопросы: 1. Первым параметром передал открытый ключ. Почему он не подхватывается и его приходится выбирать в окне диалога? 2. Как из Delphi проинициализировать и передать последний параметр: appearance? Пробовал как record - ругается. Пропускает лишь integer, поэтому пришлось изгаляться. 3. По какой причине не удаётся создать видимую подпись? Отредактировано пользователем 12 августа 2020 г. 17:54:21(UTC)
 | Причина: Не указана | 
    | 
             | 
            
         | 
    |  | 
        
        
        
            
        
            
            
    | 
	Статус: Активный участник
 Группы: Участники
 Зарегистрирован: 30.05.2018(UTC) Сообщений: 38 Сказал(а) «Спасибо»: 7 разПоблагодарили: 2 раз в 2 постах
 
 | 
            
		      
                Удалось разобраться. Выкладываю ответ, может пригодится кому-то ещё.
 Модифицировал CPPDFDSig.js следующим образом.
 
 перед строкой
 CPSign = app.trustedFunction(function(certificateHEX, pin, pdfLockMode, signReason, signLocation, signContactInfo, timeStamp, bShowCertificatesDialog, bShowSignDialogs, appearance, cadesType) {
 
 Добавил 2 переменные
 var myCoords = {left: 539, bottom: 122, right: 422, top: 439};
 var myAppearance = {pageNumber: 0, coords: [myCoords.left, myCoords.bottom, myCoords.right, myCoords.top], appearanceFilter: "fancy" };
 
 Изменил строку
 if (typeof (appearance) === 'undefined') appearance = null;
 на
 if (typeof (appearance) === 'undefined') appearance = myAppearance;
 
 Прямо в функцию не вставлял, поскольку почему-то не подхватывались координаты из Delphi.
 
 Изменил строку
 var appearanceCoords = [0, 0, 0, 0];
 на
 var appearanceCoords = [myCoords.left, myCoords.bottom, myCoords.right, myCoords.top];
 
 закомментировал строку
 if (typeof (appearance.coords) !== 'undefined') appearanceCoords = appearance.coords;
 
 В Delphi, перед вызовом CPSign инициализирую переменные.
 
 jso := PDDoc.GetJSObject;
 jso.myCoords.left := 10;
 jso.myCoords.bottom := 12;
 jso.myCoords.right := 422;
 jso.myCoords.top := 239;
 jso.MyAppearance.PageNumber := PDDoc.GetNumPages - 1;
 jso.MyAppearance.appearanceFilter := '"MyFilter"';
 
 И они корректно подхватываются.
 | 
    | 
             | 
            
         | 
    |  | 
        
        
        
    
        
            
            
    | 
	Статус: Активный участник
 Группы: Участники
 Зарегистрирован: 30.05.2018(UTC) Сообщений: 38 Сказал(а) «Спасибо»: 7 разПоблагодарили: 2 раз в 2 постах
 
 | 
            
		      
                Теперь пытаюсь разобраться с передаваемым сертификатом, чтобы подписывание шло в автоматическом режиме без дополнительных диалоговых окон. Использую тестовый сертификат КриптоПро с алгоритмом подписи ГОСТ Р 34.11-2012/34.10-2012 256 бит. Передаю открытый ключ '044030df6b9.....'. На закладке "Подписи" выводится "Неподписанные поля подписи\CPPDFDSig signature на странице 2", и чтобы подписать, требуется щёлкнуть мышкой по полю подписи и выбрать сертификат с этим открытым ключом. После этого подписывает.Передаю этот же открытый ключ в другом виде - '04 40 30 df 6b 9....', передаю отпечаток сертификата, серийный номер, пустую строку в CPSign - результат один и тот же: ничего не ломается и не подписывается Подписывается только при вызове диалога подписи.
 Как это исправить?
 
 КриптоПро CSP 4.0.9944,
 КриптоПро PDF 2.0.1180
 Windows 8.1
 | 
    | 
             | 
            
         | 
    |  | 
        
        
        
            
        
            
            
    | 
	Статус: Сотрудник
 Группы: Участники
 Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,969  Сказал «Спасибо»: 605 разПоблагодарили: 2346 раз в 1842 постах
 
 | 
            
		      
                Автор: Shuraken  Теперь пытаюсь разобраться с передаваемым сертификатом, чтобы подписывание шло в автоматическом режиме без дополнительных диалоговых окон. Использую тестовый сертификат КриптоПро с алгоритмом подписи ГОСТ Р 34.11-2012/34.10-2012 256 бит. Передаю открытый ключ '044030df6b9.....'. На закладке "Подписи" выводится "Неподписанные поля подписи\CPPDFDSig signature на странице 2", и чтобы подписать, требуется щёлкнуть мышкой по полю подписи и выбрать сертификат с этим открытым ключом. После этого подписывает.Передаю этот же открытый ключ в другом виде - '04 40 30 df 6b 9....', передаю отпечаток сертификата, серийный номер, пустую строку в CPSign - результат один и тот же: ничего не ломается и не подписывается Подписывается только при вызове диалога подписи.
 Как это исправить?
 
 КриптоПро CSP 4.0.9944,
 КриптоПро PDF 2.0.1180
 Windows 8.1
 а разве в .js не написано... что там сертификат в hex, т.е. сам сертификат, а не его ОК, отпечаток..? | 
|  | 
    | 
             | 
            
         | 
    |  | 
        
        
        
    
        
            
            
    | 
	Статус: Активный участник
 Группы: Участники
 Зарегистрирован: 30.05.2018(UTC) Сообщений: 38 Сказал(а) «Спасибо»: 7 разПоблагодарили: 2 раз в 2 постах
 
 | 
            
		      
                Автор: Андрей *  а разве в .js не написано... что там сертификат в hex, т.е. сам сертификат, а не его ОК, отпечаток..?
 
 Благодарю за идею. Попробовал указать путь к файлу - результат не изменился. А так действовал по руководству, где сказано следующее: certificateHEX String Обязательный параметр. Массив байт сертификата, используемого для создания ЭП, в виде строки шестнадцатеричных цифр. Сертификат должен быть установлен в хранилище «Личные» текущего пользователя и иметь ссылку на закрытый ключ. | 
    | 
             | 
            
         | 
    |  | 
        
        
        
            
        
            
            
    | 
	Статус: Сотрудник
 Группы: Участники
 Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,969  Сказал «Спасибо»: 605 разПоблагодарили: 2346 раз в 1842 постах
 
 | 
            
		      
                Автор: Shuraken  Автор: Андрей *  а разве в .js не написано... что там сертификат в hex, т.е. сам сертификат, а не его ОК, отпечаток..?
 
 Благодарю за идею. Попробовал указать путь к файлу - результат не изменился. А так действовал по руководству, где сказано следующее: certificateHEX String Обязательный параметр. Массив байт сертификата, используемого для создания ЭП, в виде строки шестнадцатеричных цифр.  Сертификат должен быть установлен в хранилище «Личные» текущего пользователя и иметь ссылку на закрытый ключ. Путь? Нужно сертификат... массив байт в HEX. | 
|  | 
    | 
              1 пользователь поблагодарил Андрей * за этот пост. |  | 
    |  | 
        
        
        
    
        
            
            
    | 
	Статус: Активный участник
 Группы: Участники
 Зарегистрирован: 30.05.2018(UTC) Сообщений: 38 Сказал(а) «Спасибо»: 7 разПоблагодарили: 2 раз в 2 постах
 
 | 
            
		      
                Автор: Андрей *  Путь? Нужно сертификат... массив байт в HEX.
 
 Благодарю, разобрался. Необходимо выгрузить PCCERT_CONTEXT.pbCertEncoded. Ещё один момент. Откуда брать URL службы штампов времени? Можно пример? Отредактировано пользователем 14 августа 2020 г. 17:31:28(UTC)
 | Причина: Не указана | 
    | 
             | 
            
         | 
    |  | 
        
        
        
            
        
            
            
    | 
	Статус: Сотрудник
 Группы: Участники
 Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,969  Сказал «Спасибо»: 605 разПоблагодарили: 2346 раз в 1842 постах
 
 |  | 
|  | 
    | 
             | 
            
         | 
    |  | 
        
        
        
    
        
            
            
    | 
	Статус: Активный участник
 Группы: Участники
 Зарегистрирован: 30.05.2018(UTC) Сообщений: 38 Сказал(а) «Спасибо»: 7 разПоблагодарили: 2 раз в 2 постах
 
 | 
            
		      
                Каждый параметр даётся с боем :-)Указываю в вызове функции CPSign timestamp = 'http://testca.cryptopro.ru/tsp/tsp.srf' или 'http://ocsp.ntssoft.ru/tsp/tsp.srf' - штамп времени не ставится.
 Запускаю CPSign с параметрами bShowCertificatesDialog=true, bShowSignDialogs=true. В окне выбора сертификата включена галочка "Добавить штамп времени на подпись", но не указана служба tsp. Перед этим установил КриптоПро ЭЦП Browser plug-in 2.0, КриптоПро ЭЦП SDK 2.0
 
 Также столкнулся с проблемой appearanceFilter. В оформлении цифровых подписей создал два шаблона: "t_est", "test". В CPPDFDSig перед вызовом функции CPSign объявил три переменные.
 
 var myCoords = {left: 539, bottom: 122, right: 422, top: 439};
 var filter = {Name: "test" };
 var myappearance = {pageNumber: 0, coords: [myCoords.left, myCoords.bottom, myCoords.right, myCoords.top], appearanceFilter: filter.Name };
 
 код signatureField.signatureSetSeedValue({ appearanceFilter: appearance.appearanceFilter });
 заменил на signatureField.signatureSetSeedValue({ appearanceFilter: filter.Name });
 
 код if (typeof (appearance.coords) !== 'undefined') appearanceCoords = appearance.coords;
 заменил на if (typeof (appearance.coords) !== 'undefined') appearanceCoords = [myCoords.bottom, myCoords.left, myCoords.right, myCoords.top]; //appearance.coords
 
 Если вызываю CPSign с параметрами bShowCertificatesDialog=false, bShowSignDialogs=false, то создаётся видимая подпись со стандартным, а не заданным оформлением.
 bShowSignDialogs=true - видимая подпись, но подхватывается первое оформление из списка, а не заданное.
 
 Непонятно следующее. В коде Delphi пишу
 jso := PDDoc.GetJSObject;
 jso.myappearance.pageNumber := PDDoc.GetNumPages - 1; - номер подхватывается без вопросов и печать ставится на последней странице.
 
 Задаю myCoords в Delphi, и в коде координаты подхватываются без проблем.
 
 Но оформление не подхватывается ни из кода Delphi, ни из кода CPPDFDSig. Скажите пожалуйста, как выполнить код CPSign в отладчике, чтобы увидеть, какие параметры подхватываются, а какие нет. Или объясните, как подхватить заданное оформление.
 | 
    | 
             | 
            
         | 
    |  | 
        
        
        
            
        
            
            
    | 
	Статус: Активный участник
 Группы: Участники
 Зарегистрирован: 30.05.2018(UTC) Сообщений: 38 Сказал(а) «Спасибо»: 7 разПоблагодарили: 2 раз в 2 постах
 
 | 
            
		      
                Разобрался со штампом времени. Для проставления необходимо в CPSign передать cadestype = 5 или cadestype = 93.Также разобрался с шаблоном оформления подписи. Если вызвать CPSign с параметром bShowSignDialogs=true, то в диалоговом окне будет выбор шаблона. bShowSignDialogs=false, и за параметры оформления отвечает переменная var signatureParameters = { reason: signReason, location: signLocation, contactInfo: signContactInfo, oCustomAppearance: customAppearance };
 Если изменить эту переменную на
 var signatureParameters = { reason: signReason, location: signLocation, contactInfo: signContactInfo, appearance: "fancy"};
 то подставится шаблон оформления под названием fancy и можно установить bShowSignDialogs=false
 | 
    | 
             | 
            
         | 
    |  | 
        
        
        
    
	                           
	
    
        Быстрый переход
         
	
    
    Вы не можете создавать новые темы в этом форуме.
	
	Вы не можете отвечать в этом форуме.
	
	Вы не можете удалять Ваши сообщения в этом форуме.
	
	Вы не можете редактировать Ваши сообщения в этом форуме.
	
	Вы не можете создавать опросы в этом форуме.
	
	Вы не можете голосовать в этом форуме.
	
	
    
    
        Important Information:
        The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
        
        
More Details
        Close