我们尝试使用CAdES方法和dss-cookbook中的示例作为使用最新版本(4.6.RC1)的起点来签署PDF文档。
根据SignPdfPadesBDetached.java
的示例,我们使用PAdES
成功签署了PDF文档。但是,由于CAdES
没有示例,我们尝试调整上面的示例以使用CAdES
,但是
它没有用。具体而言,生成的PDF文档的大小仅为7k而不是预期的2.5MB,并且在尝试打开PDF时会显示以下错误:
我们假设7k实际上只是签名,以便不包括实际文件。我们使用的设置是:
相关的方法代码目前是这样的:
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
和{ {1}})类。
请注意,SD-DSS项目未托管在Maven Central存储库中,因此我们必须明确引用它:
PAdESService
此外,我相信我们在<repositories>
<repository>
<id>europa</id>
<url>https://joinup.ec.europa.eu/nexus/content/groups/public/</url>
</repository>
</repositories>
中包含了所有必需/相应的依赖项:
pom.xml
在此之前,我们还尝试了PDFBox,但根据我们想要完成的内容,文档并没有那么有用。
知道这里有什么问题吗?更改包装ENVELOPING也没有区别。使用CAdES进行签名的方法是否与PAdES示例不同,不应该用作指南?
答案 0 :(得分:4)
一般来说,
PAdES 签名是嵌入到PDF 中的特定配置文件签名。因此,您的PAdES签名PDF可以在Adobe Reader中打开,Adobe Reader可以识别签名,验证签名,并在其签名面板中显示该签名。
CAdES 签名是专门分析的签名,其中位于单独的文件中或包含签名数据。这些格式都不被Adobe Reader识别,如果单独的文件可以打开原始PDF但读者看不到签名,如果包含PDF,则Reader无法打开文件或(如Reader忽略了一些前导和尾随的额外字节)考虑签名可忽略的垃圾。
您只需要一个用于PAdES签名的PDF感知库(如PDFBox),对于CAdES签名,PDF将被视为通用数据字节。
在您的情况下 ,即
您的7K确实仅仅是单独文件中的签名,您必须保留或转发PDF和签名,PDF以供查看和签名以进行验证。
因此,
具体而言,生成的PDF文档的大小仅为7k而不是预期的2.5MB ......
我们假设7k实际上只是签名,因此不包括实际文档。
您的假设是正确的,行为也是正确的。 Yout的期望是个问题。
一些混淆 可能是由于以下事实导致在PAdES签名的情况下嵌入到PDF中的签名容器在提取时被证明是CAdES格式,匹配的PDF子过滤器称为 ETSI.CAdES.detached ,并且(至少在最近的草案中)PDF 2.0规范将在标题为&#34; <的部分中处理PAdES签名。 em> 12.8.3.4 PDF(PDF 2.0)中使用的CAdES签名&#34;。
尽管如此,如果您正在谈论PAdES签名,您谈论的是集成在PDF中的ETSI AdES签名。如果您正在谈论CAdES签名,那么您所谈论的是独立于特定文档格式的ETSI AdES CMS签名,这些签名可能与签名数据分离或者可能包含它们。
根据您的评论,特别是这个
使用
ETSI.CAdES.DETACHED
过滤器签署PDF是确切的要求
你最终不想要创建一个 CAdES 签名,而是 PAdES 签名,更确切地说,你想要这样做到第3部分:PAdES增强 - PAdES-BES和PAdES-EPES配置文件而不是根据第2部分:PAdES Basic - 基于ISO 32000-1的配置文件使用子过滤器 adbe.pkcs7.detached 和 adbe.pkcs7.sha1 。
(要获得直接要求,即子过滤器值,而不是过滤器值。)
这正是dss cookbook示例SignPdfPadesB
,SignPdfPadesBDetached
和SignPdfPadesBVisible
的全部内容:
并且该标准指定:
6 B级一致性要求
本条款定义了声称符合B级要求的PAdES签名必须满足的要求。
现行条款规定了短期电子签名的合规要求。本条实际上是个人资料 PAdES-BES(不包含
signature-policy-identifier
的签名)和PAdES-EPES(签名 确实包含signature-policy-identifier
)签名。
不幸的是,我现在无法验证样本是否符合他们的要求,因为我的日食dss项目都有问题。
但是,如果他们这样做,那么看起来你刚开始已经拥有了你想要的东西:
按照SignPdfPadesBDetached.java的示例,我们使用PAdES成功签署了PDF文档。
您可以与该示例共享一份PDF样本,以便进行分析。