Не удается подписать PDF с помощью метода CAdES, хотя подпись с помощью PAdES прошла успешно
Мы пытаемся подписать документ PDF с использованием метода CAdES и примеров из dss-cookbook в качестве отправной точки, используя самую последнюю версию (4.6.RC1).
Следуя примеру из SignPdfPadesBDetached.java
мы успешно подписали PDF документ, используя PAdES
, Тем не менее, так как нет примера для CAdES
мы попытались адаптировать приведенный выше пример для использования CAdES
, но это не работает. В частности, сгенерированный PDF-документ имеет размер всего 7 КБ вместо ожидаемых 2,5 МБ, и при попытке открыть PDF-файл отображается следующая ошибка:
Мы предполагаем, что 7k на самом деле является только подписью, поэтому фактический документ не включен. Настройки, которые мы используем:
- SignatureLevel.CAdES_BASELINE_B
- SignaturePackaging.DETACHED
- DigestAlgorithm.SHA256
И код метода родственника в настоящее время это:
public static void signPdfWithCades(DSSDocument toSignDocument) {
LOG.info("Signing PDF with CADES B");
try {
AbstractSignatureTokenConnection signingToken = new Pkcs12SignatureToken("password", KEYSTORE_PATH);
DSSPrivateKeyEntry privateKey = signingToken.getKeys().get(0);
// Preparing parameters for the CAdES signature
CAdESSignatureParameters parameters = new CAdESSignatureParameters();
// We choose the level of the signature (-B, -T, -LT, -LTA).
parameters.setSignatureLevel(SignatureLevel.CAdES_BASELINE_B);
// We choose the type of the signature packaging (ENVELOPING, DETACHED).
parameters.setSignaturePackaging(SignaturePackaging.DETACHED);
// We set the digest algorithm to use with the signature algorithm. You must use the
// same parameter when you invoke the method sign on the token. The default value is
// SHA256
parameters.setDigestAlgorithm(DigestAlgorithm.SHA256);
// We set the signing certificate
parameters.setSigningCertificate(privateKey.getCertificate());
// We set the certificate chain
parameters.setCertificateChain(privateKey.getCertificateChain());
// Create common certificate verifier
CommonCertificateVerifier commonCertificateVerifier = new CommonCertificateVerifier();
// Create PAdES xadesService for signature
CAdESService service = new CAdESService(commonCertificateVerifier);
// Get the SignedInfo segment that need to be signed.
ToBeSigned dataToSign = service.getDataToSign(toSignDocument, parameters);
// This function obtains the signature value for signed information using the
// private key and specified algorithm
DigestAlgorithm digestAlgorithm = parameters.getDigestAlgorithm();
SignatureValue signatureValue = signingToken.sign(dataToSign, digestAlgorithm, privateKey);
// We invoke the cadesService to sign the document with the signature value obtained in
// the previous step.
DSSDocument signedDocument = service.signDocument(toSignDocument, parameters, signatureValue);
LOG.info("Signed PDF size = " + signedDocument.getBytes().length);
//We use the DSSUtils to Save to file
DSSUtils.saveToFile(signedDocument.openStream(), "target/signedPdfCadesBDetached.pdf");
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
Соответствующий метод для подписи с PAdES
аналогично приведенному выше, с поправкой на PAdES
(то есть мы там использовали PAdESSignatureParameters
, SignatureLevel.PAdES_BASELINE_B
а также PAdESService
) занятия.
Обратите внимание, что проект SD-DSS не размещается в репозитории Maven Central, поэтому нам пришлось сделать явную ссылку на него:
<repositories>
<repository>
<id>europa</id>
<url>https://joinup.ec.europa.eu/nexus/content/groups/public/</url>
</repository>
</repositories>
Кроме того, я считаю, что мы включили все необходимые / соответствующие зависимости в нашем pom.xml
:
<dependency>
<groupId>eu.europa.ec.joinup.sd-dss</groupId>
<artifactId>dss-token</artifactId>
<version>4.6.RC1</version>
</dependency>
<dependency>
<groupId>eu.europa.ec.joinup.sd-dss</groupId>
<artifactId>dss-pades</artifactId>
<version>4.6.RC1</version>
</dependency>
<dependency>
<groupId>eu.europa.ec.joinup.sd-dss</groupId>
<artifactId>dss-cades</artifactId>
<version>4.6.RC1</version>
</dependency>
<dependency>
<groupId>eu.europa.ec.joinup.sd-dss</groupId>
<artifactId>dss-document</artifactId>
<version>4.6.RC1</version>
</dependency>
До этого мы также попробовали PDFBox, но документация не была настолько полезной, в зависимости от того, чего мы хотим достичь.
Есть идеи, что здесь не так? Смена упаковки ENVELOPING также не имеет значения. Является ли метод подписи с помощью CAdES настолько разным, что пример PAdES не следует использовать в качестве руководства?
1 ответ
В общем,
Подписи PAdES - это специально профилированные подписи, встроенные в PDF. Таким образом, PDF-файл с вашей подписью PAdES можно открыть в Adobe Reader, и Adobe Reader может распознать подпись, проверить ее и отобразить результат на своей панели подписи.
Подписи CAdES - это специально профилированные подписи, которые либо находятся в отдельном файле, либо содержат подписанные данные. Ни один из этих форматов не распознается Adobe Reader, в случае отдельного файла вы можете открыть исходный PDF, но Reader не видит подпись, в случае содержащегося PDF Reader либо не может открыть файл вообще, либо (как Читатель игнорирует некоторые ведущие и конечные дополнительные байты) считает подпись игнорируемым мусором.
Вам нужна только библиотека с поддержкой PDF (например, PDFBox) для подписей PAdES, для подписей CAdES PDF обрабатывается как байты общих данных.
В вашем случае, следовательно, то есть для
- SignatureLevel.CAdES_BASELINE
- SignaturePackaging.DETACHED
Ваш 7K действительно является простой подписью в отдельном файле, и вы должны хранить или пересылать как PDF, так и подпись, PDF для просмотра и подпись для проверки.
Таким образом,
В частности, сгенерированный PDF-документ имеет размер всего 7 КБ вместо ожидаемых 2,5 МБ...
Мы предполагаем, что 7k на самом деле является только подписью, поэтому фактический документ не включен.
Ваше предположение правильно, а также поведение правильно. Yout ожидания являются проблемой.
Некоторая путаница может возникнуть из-за того факта, что контейнер для подписи, встроенный в PDF в случае подписи PAdES, при извлечении оказывается в формате CAdES, что соответствующий подфильтр PDF называется ETSI.CAdES.detached и что (по крайней мере, в последнем проекте) спецификация PDF 2.0 будет обрабатывать сигнатуры PAdES в разделе, озаглавленном " 12.8.3.4 Подписи CAdES, используемые в PDF (PDF 2.0) ".
Тем не менее, если вы говорите о сигнатурах PAdES, вы говорите о сигнатурах ETSI AdES, интегрированных в PDF-файлы. Если вы говорите о сигнатурах CAdES, вы говорите о сигнатурах ETSI AdES CMS независимо от конкретного формата документа, который может быть отделен от подписанных данных или может обернуть их.
Согласно вашим комментариям, в частности, этот
Подписание PDF с помощью
ETSI.CAdES.DETACHED
фильтр является точным требованием
В конце концов, вы не хотите создавать подпись CAdES, а вместо этого подпись PAdES, точнее, вы хотите сделать это в соответствии с Частью 3: Расширенные PAdES - Профили PAdES-BES и PAdES-EPES, а не согласно Части 2: PAdES Базовый - профиль на основе ISO 32000-1, который использует подфильтры adbe.pkcs7.detached и adbe.pkcs7.sha1.
(Чтобы прояснить требование, это значение подфильтра, а не значение фильтра.)
Это именно то, что примеры поваренной книги dss SignPdfPadesB
, SignPdfPadesBDetached
, а также SignPdfPadesBVisible
должно быть все о:
- все они в своем комментарии к классу JavaDoc утверждают, что показывают, как подписывать PDF документ с помощью PAdES-BASELINE-B,
- поваренная книга asciidoc/dss- Documentation.adoc для PAdES Базовые профили относятся к ETSI TS 103 172,
и этот стандарт определяет:
6 Требования для соответствия уровня B
В этом пункте определяются требования, которые должны выполнять подписи PAdES, претендующие на соответствие B-уровню.
Текущий пункт определяет требования соответствия для краткосрочных электронных подписей. В этом пункте фактически описываются PAdES-BES (подписи, которые не включают
signature-policy-identifier
) и PAdES-EPES (подписи, которые включаютsignature-policy-identifier
) подписи.
К сожалению, я не могу сейчас проверить, что примеры делают то, что заявляют, так как все мои проекты eclipse dss красны с проблемами.
Если они это сделают, то, похоже, у вас в начале уже было то, что вы хотели:
Следуя примеру из SignPdfPadesBDetached.java, мы успешно подписали документ PDF с использованием PAdES.
Вы можете предоставить образец PDF-файла, подписанный этим примером, чтобы быть уверенным в анализе.