0

我在尝试对 PDF 文档进行数字签名时遇到此错误。传递两个 pdf SOURCEPDF 名称和 DESTINATIONPDF 名称(数字签名)pdf 名称。在 SOURCEPDF 上进行第一次数字签名后,我得到了 DESTINATIONPDF 。对于第二次数字签名,我使用 DESTINATIONPDF 作为源 pdf 和目标 pdf。

这是我的代码

try
{
    for(int i=1;i<=signature_Count;i++)
    {
        if(i==1)
        {
            tmpPdfSource=sourcePdfPath;
        }else{
            this.tmpPdfSource=destinationPdfPath;
        }

        int pageNo=Integer.parseInt(ad.readXML(xmlString, rootName,"PageNo-"+i));
        String imageSource=ad.readXML(xmlString, rootName,"ImageSource-"+i);
        float llx=Float.parseFloat(ad.readXML(xmlString, rootName,"llx-"+i));
        float lly=Float.parseFloat(ad.readXML(xmlString, rootName,"lly-"+i));
        float urx=Float.parseFloat(ad.readXML(xmlString, rootName,"urx-"+i));
        float ury=Float.parseFloat(ad.readXML(xmlString, rootName,"ury-"+i));
        String signature=ad.readXML(xmlString, rootName,"SignatureName-"+i);

        File dest = new File(destinationPdfPath);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(new Fil eInputStream(certificatePath), keystore_password.toCharArray());
        String alias = (String) ks.aliases().nextElement();
        PrivateKey pk = (PrivateKey) ks.getKey(alias,key_password.toCharArray());
        java.security.cert.Certificate[] chain = ks.getCertificateChain(alias);
        PdfReader reader = new PdfReader(tmpPdfSource);
        stamper = PdfStamper.createSignature(reader,new FileOutputStream(dest), '\0', null, true);
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();

        appearance.setCrypto(pk, chain, null,PdfSignatureAppearance.SELF_SIGNED);

        if (true)
        {
            appearance.setAcro6Layers(true);
            Image img=Image.getInstance(imageSource);
            appearance.setImage(img);
            appearance.setVisibleSignature(new com.itextpdf.text.Rectangle(llx, lly, urx, ury), pageNo, signature);
        }
    }//for
    stamper.close();
} catch (Exception e) {
    GenericLog gl=new  GenericLog();
    gl.writeWarning("Error Occured in SignPdfDocument ");
    gl.writeError(e);
    e.printStackTrace();
}

请帮我修复这个错误。

4

2 回答 2

1

重新格式化代码以使其可读后,问题变得明显:

for(int i=1;i<=signature_Count;i++)
{
    if(i==1)
    {
        tmpPdfSource=sourcePdfPath;
    }else{
        this.tmpPdfSource=destinationPdfPath;
    }
    [...]
    File dest = new File(destinationPdfPath);
    [...]
    PdfReader reader = new PdfReader(tmpPdfSource);
    stamper = PdfStamper.createSignature(reader,new FileOutputStream(dest), '\0', null, true);
    [...]
}//for
stamper.close();

从第二次迭代开始,您读取PdfStamper上一次迭代中生成的文件,您必须stamper在迭代结束时关闭它,而不是在for循环之外:

    stamper = PdfStamper.createSignature(reader,new FileOutputStream(dest), '\0', null, true);
    [...]
    stamper.close();
}//for

此外,您最好new FileOutputStream(dest)在关闭后立即将您的变量放入变量中并显式关闭它stamper:

    FileOutputStream fout = new FileOutputStream(dest);
    stamper = PdfStamper.createSignature(reader, fout, '\0', null, true);
    [...]
    stamper.close();
    fout.close();
}//for

当然,听从 Bruno 的建议,阅读他的 PDF 签名白皮书,并更新您的签名创建代码以生成非弃用类型的签名。

于 2013-02-12T14:55:00.823 回答
0

我看到了这个方法setCrypto(),这意味着你没有使用最新版本的 iText;我还看到了这个选项PdfSignatureAppearance.SELF_SIGNED,这意味着您正在创建一个不再符合当今标准的签名。

您能帮自己一个忙并阅读文档吗?

另外:您使用与源和目标相同的文件?这不可能。您至少需要创建一个临时文件或在内存中创建文件,然后覆盖现有文件。

于 2013-02-12T13:52:23.037 回答