当前位置: 首页 > 知识库问答 >
问题:

PDFBox:签名失败“无法写入签名,空间不足”

司空朝
2023-03-14

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

我的代码的签名部分是:

            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)

我不知道为什么这行不通...

任何帮助都将不胜感激!=)

共有1个答案

尹雅健
2023-03-14

在评论中你提到你得到

签名长度=10721

在日志文件中

没有设置任何首选尺寸

默认情况下,PDFBox为签名保留0x2500字节。十进制为9472字节。因此,就像异常所说的,没有足够的空间。

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

SignatureOptions signatureOptions = new SignatureOptions();
signatureOptions.setPreferredSignatureSize(20000);
document.addSignature(signature, signatureOptions);
 类似资料:
  • PDF创建步骤: 通过添加空签名字段名称创建pdf:suhasb@gmail.com和nikhil.courser@gmail.com,使用原始的hello.pdf输出文件名hello_tag.pdf运行程序>tagpdfsignaturefields.java 从hello_tag.pdf文件中提取签名字段suhasb@gmail.com进行首次签名,输出文件名为hello_signd.pdf

  • 当我重新启动identityserver4客户端应用程序第一次获得异常时,我使用identityserver4处理SSO问题 因此,我将更改为但在重新启动identityserver时仍然会出现错误

  • 我在PDF文档中(以编程方式)填写一个表单(AcroPdf),然后在文档上签名。我从doc.pdf开始,使用pdfbox的setfields.java示例创建doc_filler.pdf。然后我对doc_fill.pdf进行签名,创建doc?filled_signer.pdf,使用一些代码,基于签名示例并在Acrobat Reader中打开pdf。输入的字段数据是可见的,并且签名面板告诉我 “此签

  • 这是接口签名 这是类签名者 我用java和bouncycastle创建了证书和密钥对,我现在不知道是问题还是我做错了什么?

  • 我的要求是:在网站上,用户可以点击[我们的]平台上的签名按钮,直接弹出要签名的文档并在文档上签名 目前,根据DocuSign嵌入式发送和签名文档,我们使用JWT admin授权方法获取访问权\uu用户可以通过文档“envelopeviews:create recipient”打开并签署文档URL, 问题: 如果我们直接复制DocuSign URL并在浏览器中打开它,页面将正确显示要签名的文档页面。

  • 我正在生成一个XML Xades签名。我需要在标记签名中添加名称空间http://uri.etsi.org/01903/v1.3.2#。 如果我在对文档签名后添加此标记,我将得到无效签名错误。 我需要命名空间将在标记签名中而不是标记对象中