PDFBox:签名失败 "Can't write signature, not enough space"

PDFBox : Signature fails "Can't write signature, not enough space"

我在 JAVA 中使用 PDFBox 实现了签名功能。

我的代码的签名部分是:

            ExternalSigningSupport externalSigning = document.saveIncrementalForExternalSigning(output);
            byte[] cmsSignature = new byte[0];
            
            try {
                
                Certificate[] certificationChain = SignatureUtils.getCertificateChain(alias);
                X509Certificate certificate = (X509Certificate) certificationChain[0];
                PrivateKey privateKey = SignatureUtils.getSignaturePrivateKey(alias, password);
                
                CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
                ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey);
                gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build())
                                .build(sha1Signer, certificate));
                gen.addCertificates(new JcaCertStore(Arrays.asList(certificationChain)));
                CMSProcessableInputStream msg = new CMSProcessableInputStream(externalSigning.getContent());
                CMSSignedData signedData = gen.generate(msg, false);
                
                if (tsaUrl != null && !tsaUrl.isEmpty()) {
                    ValidationTimeStamp validation;
                    validation = new ValidationTimeStamp(tsaUrl);
                    signedData = validation.addSignedTimeStamp(signedData);
                }
                cmsSignature = signedData.getEncoded();
                
                if (logger.isDebugEnabled()) {
                    logger.debug("signature length = " + cmsSignature.length);
                    logger.debug("certificate = " + certificate.toString());
                }
                
            } catch (GeneralSecurityException | CMSException | OperatorCreationException | IOException e) {
                throw new SignatureException(e.getMessage());
            }
            
            externalSigning.setSignature(cmsSignature);

如果我使用通过 keytool 命令生成的测试自动签名证书,一切正常。

问题是,当我使用真正经过认证的现有证书尝试此代码时,我得到了例外:

Caused by: java.io.IOException: Can't write signature, not enough space
        at org.apache.pdfbox.pdfwriter.COSWriter.writeExternalSignature(COSWriter.java:797)
        at org.apache.pdfbox.pdmodel.interactive.digitalsignature.SigningSupport.setSignature(SigningSupport.java:48)

我不知道为什么这不起作用...

如有任何帮助,我们将不胜感激! =)

在评论中你提到你得到了

signature length = 10721

在日志文件中并且您

didn't set any preferred size

PDFBox默认为签名保留0x2500字节。这是十进制的 9472 字节。因此,就像异常所说的那样,不够 space.

您可以在 document.addSignature 期间使用 SignatureOptions 对象设置 PDFBox 为签名保留的大小:

SignatureOptions signatureOptions = new SignatureOptions();
signatureOptions.setPreferredSignatureSize(20000);
document.addSignature(signature, signatureOptions);