Статус: Новичок
Группы: Участники
Зарегистрирован: 14.05.2026(UTC) Сообщений: 5
|
Добрый день! Пытаюсь добавить штамп ЭП в PDF файл по откреплённой подписи. Откреплённую подпись тоже нужно сохранять. Сервер на C# .net core формирует PDF файл, затем с помощью iTextSharp добавляется штамп, вычисляется хэш по выбранному алгоритму и вместе с измененным PDF отправляется на клиент Клиент на JS и Jquery подписывает хэш с помощью КриптоПро browser plugin, затем подпись отправляется обратно На сервере пытаюсь вставить подпись в мой штамп, но после проверки через Acrobat Reader с установленным КриптоПро PDF, подпись недействительна Собственно почему так происходит и как добавлять несколько подписей если хэш по сути будет меняться Код формирования штампа и расчет хэша
using var reader = new PdfReader(file.Path); using var ms = new MemoryStream();
var stamper = PdfStamper.CreateSignature(reader, ms, '\0');
var appearance = stamper.SignatureAppearance; appearance.Reason = "Подписание"; appearance.Location = "RU";
appearance.SetVisibleSignature( new iTextSharp.text.Rectangle(36, 748, 200, 800), 1, "Signature_" + UserProfile.FullName );
iTextSharp.text.pdf.security.IExternalSignatureContainer external = new EmptySignatureContainer(); MakeSignature.SignExternalContainer(appearance, external, 8192);
dicFileHash.Add("Hash", string.Join(string.Empty, hashAlgorithm.ComputeHash(pdf).Select(b => b.ToString("X2")))); dicFileHash.Add("Content", Convert.ToBase64String(pdf));
Код записи подписи в штамп
System.IO.File.WriteAllBytes(file.Path, Convert.FromBase64String(dicFileSig["Content"])); using var reader = new PdfReader(file.Path); using var output = new MemoryStream();
var container = new ExternalSignatureContainer(Convert.FromBase64String(dicFileSig["Signature"])); MakeSignature.SignDeferred(reader, "Signature_" + UserProfile.FullName, output, container);
reader.Close();
System.IO.File.WriteAllBytes(file.Path, output.ToArray());
Ошибка после вставки подписи в штамп
 1.png (10kb) загружен 2 раз(а). 2.png (29kb) загружен 2 раз(а).
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 24.02.2026(UTC) Сообщений: 19  Откуда: Москва Сказал(а) «Спасибо»: 1 раз Поблагодарили: 5 раз в 5 постах
|
Автор: Ильдар Якшибаев  Клиент на JS и Jquery подписывает хэш с помощью КриптоПро browser plugin, затем подпись отправляется обратно Как подписываете хэш на клиенте? Можете приложить код? Подпишите также люблой PDF документ и пришлите его вместе с вычисленной ХЭШ суммой (которую отправили бы на подписание). Проверю, правильно ли она вычисляется.
|
|
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 14.05.2026(UTC) Сообщений: 5
|
Код подписания на JS
let cert = that.certsContainer[certIndex];
let hashObject = yield cadesplugin.CreateObjectAsync("CAdESCOM.HashedData"); let coHashObject = yield cadesplugin.CreateObjectAsync("CAdESCOM.HashedData");
let certPublicKey = yield cert.PublicKey(); let certAlgorithm = yield certPublicKey.Algorithm; let algorithmValue = yield certAlgorithm.Value;
if (algorithmValue === "1.2.643.7.1.1.1.1") { yield hashObject.propset_Algorithm(cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256); yield coHashObject.propset_Algorithm(cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256); } else if (algorithmValue === "1.2.643.7.1.1.1.2") { yield hashObject.propset_Algorithm(cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_512); yield coHashObject.propset_Algorithm(cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_512); } else if (algorithmValue === "1.2.643.2.2.19") { yield hashObject.propset_Algorithm(cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411); yield coHashObject.propset_Algorithm(cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411); } else { errorModal("Невозможно подписать документ этим сертификатом"); return; }
let oSigner = yield cadesplugin.CreateObjectAsync("CAdESCOM.CPSigner");
yield oSigner.propset_Certificate(cert);
yield hashObject.SetHashValue(data.Hash); yield coHashObject.SetHashValue(data.Hash);
var oDocumentNameAttr = yield cadesplugin.CreateObjectAsync("CADESCOM.CPAttribute"); yield oDocumentNameAttr.propset_Name(CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME); yield oDocumentNameAttr.propset_Value(data.Name);
var oAuthAttrs = yield oSigner.AuthenticatedAttributes2; yield oAuthAttrs.Add(oDocumentNameAttr);
let oSignedData = yield cadesplugin.CreateObjectAsync("CAdESCOM.CadesSignedData"); oSignedData.propset_ContentEncoding(cadesplugin.CADESCOM_BASE64_TO_BINARY); let signatureHex = yield oSignedData.SignHash(hashObject, oSigner, 1);
if (data.CoSignature == "") { data.CoSignature = signatureHex; data.Signature = signatureHex; } else { yield oSignedData.VerifyHash(coHashObject, data.CoSignature, 1); let coSignatureHex = yield oSignedData.CoSignHash(hashObject, oSigner, 1); data.CoSignature = coSignatureHex; data.Signature = signatureHex; }
Хэш
89E8BCB6E20EB80D93D9A0A35158BC003757A00994BA512FD65F431FC7376B71
 3ec3bdd5-8422-440c-a8da-cd6439255aa3 original.pdf (29kb) загружен 4 раз(а). 3ec3bdd5-8422-440c-a8da-cd6439255aa3.pdf (46kb) загружен 2 раз(а).
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 14,162   Сказал «Спасибо»: 618 раз Поблагодарили: 2389 раз в 1880 постах
|
3ec3bdd5-8422-440c-a8da-cd6439255aa3 original.pdf = EA269B96695308B3AA337DEB1458C51E43C0091A1889621EF2D80558D3173115 3ec3bdd5-8422-440c-a8da-cd6439255aa3.pdf = 5B1ABFC739BAA7981B2FD5B3D9DC1F4555ECC68714059A5CE2486730EAC284EE
|
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 24.02.2026(UTC) Сообщений: 19  Откуда: Москва Сказал(а) «Спасибо»: 1 раз Поблагодарили: 5 раз в 5 постах
|
Хэш от подписываемых данных в 3ec3bdd5-8422-440c-a8da-cd6439255aa3.pdf - DE0BFD3DB83B4BDDDCAD57494805810F8BE16DBCA335561E028AAF90DAEFD914 Так понимаю, вы получили хэш от всего документа PDF после создания пустой подписи. Но для подписи PDF подписывается не весь документ, а два сегмента данных в /Root/AcroForm/Fields/V/ByteRange В документации LibCore есть пример: https://dss.cryptopro.ru...F%D0%B8%D1%81%D1%8C.htmlМожно взять его за основу и заместо вычисления подписи вычислять хэш. Либо на основе вашего примера как-то получить ByteRange после вызова SignExternalContainer, и вычислить хэш от двух сегментов из него.
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 14,162   Сказал «Спасибо»: 618 раз Поблагодарили: 2389 раз в 1880 постах
|
|
|
|
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 14.05.2026(UTC) Сообщений: 5
|
Странно, я делал через ByteRange и у меня сначала не получилось, а сейчас всё сработало, но есть другая проблема, откреплённая подпись теперь недействительна и как я понимаю соподписание файла тоже не получится сделать т.к. я возьму в расчет хэша предыдущую подпись
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 24.02.2026(UTC) Сообщений: 19  Откуда: Москва Сказал(а) «Спасибо»: 1 раз Поблагодарили: 5 раз в 5 постах
|
Да, сделать так, чтобы проверялась и откреплённая подпись, и подпись в PDF нельзя, так как подписываются разные данные. В случае с PDF подписью - это набор байт исходного PDF документа и элемента штампа (тут я упрощаю, но суть примерно такая). Между этими двумя отрезками байт помещаются байты подписи. А в случае с откреплённой подписью - подписывается весь PDF документ.
|
|
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 14.05.2026(UTC) Сообщений: 5
|
А как тогда происходит подпись через КриптоПро PDF, я подписал PDF откреплённой подписью, затем добавил подпись через КриптоПро PDF и проверил откреплённую подпись, и подпись прошла проверку
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 24.02.2026(UTC) Сообщений: 19  Откуда: Москва Сказал(а) «Спасибо»: 1 раз Поблагодарили: 5 раз в 5 постах
|
Не уверен, как такое могло получиться. Подпись точно откреплённая создалась?
|
|
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close