iText Java 签署 PDF DocumentException: 不够 space

iText Java Signing PDF DocumentException: Not enough space

我正在为 Java 使用 iText 5.5.5,我想创建带有外部签名的签名 PDF,如下所示:

将需要签名的PDF文档创建为空签名的PDF,并提供BASE64编码的字节供外部签名机制签名:

PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '[=12=]');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "test");
appearance.setCertificate(chain[1]);
ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
MakeSignature.signExternalContainer(appearance, external, 8192);

InputStream is = appearance.getRangeStream();
byte[] toSign = getBytes(is);
this.b64String = new String(Base64.encode(toSign));

使用外部签名机制签署 b64String,提供签名作为 BASE64 中的 PKCS#7 签名数据。

创建 ExternalSignatureContainer 以仅从外部签名机制获得 PKCS#7 签名数据:

public class MyExternalSignatureContainer implements ExternalSignatureContainer {
    protected byte[] sig;

    public MyExternalSignatureContainer(byte[] sig) {
        this.sig = sig;
    }

    @Override
    public void modifySigningDictionary(PdfDictionary arg0) {
    }

    @Override
    public byte[] sign(InputStream arg0) throws GeneralSecurityException {
        return sig;
    }
}

使用 MyExternalSignatureContainer 创建签名的 PDF 文档:

PdfReader reader = new PdfReader(dest);
FileOutputStream os = new FileOutputStream(signedpdf);
ExternalSignatureContainer external = new MyExternalSignatureContainer(signedData);
MakeSignature.signDeferred(reader, "test", os, external);

但我在最后一行 MakeSignature.signDeferred(reader, "test", os, external); 出现以下异常:

com.itextpdf.text.DocumentException: Not enough space

问题出在哪里,如何解决?

您估计签名将适合 8192 字节。但是,签名的字节数byte[]超过了8192,因此异常Not enough space。例如:您的外部签名容器 returns 一个大小为 10000 字节的签名。 iText 告诉您 10000 大于 8192,而您在问一些不可能的事情。

如何解决此问题:在创建带有空签名的 PDF 时做出更好的估计。

告诉您容器的估计尺寸:

MakeSignature.signExternalContainer(appearance, external, 0);

根据MakeSignature API

estimatedSize - the reserved size for the signature. It will be estimated if 0