Статус: Новичок
Группы: Участники
Зарегистрирован: 15.04.2020(UTC) Сообщений: 8 Откуда: Москва Сказал(а) «Спасибо»: 2 раз
|
Добрый день! Стоит задача подписать pdf-файл(хэш файла), взял пример из документации itext 7 C4_09_DeferredSigning.java1. На сервере создаю pdf с пустой подписью Код: public void emptySignature(String src, String dest, String fieldname)
throws IOException, GeneralSecurityException {
PdfReader reader = new PdfReader(src);
PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), new StampingProperties());
PdfSignatureAppearance appearance = signer.getSignatureAppearance();
appearance
.setPageRect(new Rectangle(36, 748, 200, 100))
.setPageNumber(1);
//.setCertificate(chain[0]);
signer.setFieldName(fieldname);
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.Adobe_PPKLite,
PdfName.Adbe_pkcs7_detached);
signer.signExternalContainer(external, 8192);
}
2. Передаю base64 клиенту, там делаю хэш Код: var oHashedData = cadesplugin.CreateObject("CAdESCOM.HashedData");
oHashedData.Algorithm = cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256;
oHashedData.DataEncoding = cadesplugin.CADESCOM_BASE64_TO_BINARY;
oHashedData.Hash(dataInBase64);
var sHashValue = oHashedData.Value;
3. Подписываю на клиенте Код:var oSigner = cadesplugin.CreateObject("CAdESCOM.CPSigner");
oSigner.Certificate = certObject;
var oSignedData = cadesplugin.CreateObject("CAdESCOM.CadesSignedData");
var oHashedData = cadesplugin.CreateObject("CAdESCOM.HashedData");
oHashedData.Algorithm = cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256;
oHashedData.DataEncoding = 0x01;
oHashedData.SetHashValue(dataToSign);
var Signature = oSignedData.SignHash(oHashedData, oSigner, CADESCOM_CADES_BES);
return Signature;
4. Передаю подпись на сервер, на сервере вставляю в заготовленный файл pdf Код: public void createSignature(String src, String dest, String fieldName, String signature)
throws IOException, GeneralSecurityException {
byte[] decodedBytes = Base64.getDecoder().decode(signature);
PdfReader reader = new PdfReader(src);
try(FileOutputStream os = new FileOutputStream(dest)) {
PdfSigner signer = new PdfSigner(reader, os, new StampingProperties());
MyExternalSignatureContainer external = new MyExternalSignatureContainer(null, null);
external.setSignature(decodedBytes);
signer.signDeferred(signer.getDocument(), fieldName, os, external);
}
}
class MyExternalSignatureContainer implements IExternalSignatureContainer {
protected PrivateKey pk;
protected Certificate[] chain;
private byte[] signature;
public void setSignature(byte[] decodedBytes) {
this.signature = decodedBytes;
}
public MyExternalSignatureContainer(PrivateKey pk, Certificate[] chain) {
this.pk = pk;
this.chain = chain;
}
public void modifySigningDictionary(PdfDictionary signDic) {
}
@Override
public byte[] sign(InputStream arg0) throws GeneralSecurityException {
return this.signature;
}
}
Я нашел аналогичные решенные задачи, например, здесь и здесь и, как мне кажется, последовательность действий верная. Но в результате я пытаюсь проверить подпись через Adobe Reader с плагином и получаю ошибку "Ошибка при проверке - неподдерживаемый алгоритм". Пожалуйста, подскажите, в чем может быть проблема? Поддерживается ли itext7 или нужно обязательно использовать itext5.5? Спасибо
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 12,704 Сказал «Спасибо»: 500 раз Поблагодарили: 2051 раз в 1591 постах
|
Здравствуйте. Какая версия Криптопро csp на клиенте? |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 15.04.2020(UTC) Сообщений: 8 Откуда: Москва Сказал(а) «Спасибо»: 2 раз
|
Автор: Андрей * Здравствуйте. Какая версия Криптопро csp на клиенте? Версия продукта: 4.0.9944 Версия ядра СКЗИ: 4.0.9017 КС1
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 15.04.2020(UTC) Сообщений: 8 Откуда: Москва Сказал(а) «Спасибо»: 2 раз
|
Мне кажется, я как-то неправильно формирую подпись потому, что в Adobe Reader нет никакой читабельной информации, кроме времени подписи: Добавил в код подписания oSigner.Options = cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN, но это ничего не дало.
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 15.04.2020(UTC) Сообщений: 8 Откуда: Москва Сказал(а) «Спасибо»: 2 раз
|
Переписал все на версию itextpdf_patched-5.5.5 Создание пустой подписи и получение байтов для подписи Код: public byte[] emptySignature(String src, String dest, String fieldname)
throws IOException, GeneralSecurityException, DocumentException {
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, fieldname);
ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
MakeSignature.signExternalContainer(appearance, external, 8192);
byte[] data = IOUtils.toByteArray(appearance.getRangeStream());
reader.close();
return data;
}
Добавление подписи в предварительно заготовленный pdf Код: public void createSignature(String src, String dest, String fieldName, String signature)
throws IOException, GeneralSecurityException, DocumentException {
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
byte[] decodedBytes = Base64.getDecoder().decode(signature);
ExternalSignatureContainer external = new MyExternalSignatureContainer(decodedBytes);
MakeSignature.signDeferred(reader, fieldName, os, external);
reader.close();
}
class MyExternalSignatureContainer implements ExternalSignatureContainer {
protected PrivateKey pk;
protected Certificate[] chain;
private byte[] signature;
public MyExternalSignatureContainer(byte[] decodedBytes) {
this.signature = decodedBytes;
}
public void setSignature(byte[] decodedBytes) {
this.signature = decodedBytes;
}
@Override
public byte[] sign(InputStream arg0) throws GeneralSecurityException {
return this.signature;
}
@Override
public void modifySigningDictionary(PdfDictionary arg0) {
// TODO Auto-generated method stub
}
}
Сообщение в Adobe Reader не изменилось.
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 15.04.2020(UTC) Сообщений: 8 Откуда: Москва Сказал(а) «Спасибо»: 2 раз
|
Видимо, я настолько обзорно ставлю задачу или настолько далек от понимания того, что делаю, что моя проблема не получает отклика.
Попробую сформулировать более конкретные вопросы, которые потенциально может помочь продвинуться. Пожалуйста, помогите с консультацией.
1. При формировании контейнера подписи в pdf критично ли заполнение поля Certificate (appearance.setCertificate) и прочих полей (Reason, Location)? 2. Если заполнение поля Certificate обязательно, как получить сертификат на сервере, если подпись происходит на клиенте? 3. Если цепь сертификатов зашивается в подпись (CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN), можно ли её вытащить из подписи на сервере, чтобы вставить в appearance? И нужно ли это?
Заранее благодарен за ответы
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 15.04.2020(UTC) Сообщений: 8 Откуда: Москва Сказал(а) «Спасибо»: 2 раз
|
Разобрался. На самом деле код, описанный выше верный и работает (на момент написания проверял код, который на версии itext 5.5 patched).
Проблема заключалась в том, что Acrobat Reader DC по-умолчанию для проверки подписи использовал свои штатные алгоритмы, из-за этого и ошибка - неподдерживаемый алгоритм. Проблема решилась, когда я в настройках adobe reader указал плагин по-умолчанию для проверки подписей - Крипто-про плагин.
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close