我在尝试对PDF文档进行数字签名时遇到此错误。 传递两个pdfs 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();
}
请帮我修复此错误。
答案 0 :(得分: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
,而不是在{{1}之外}环
for
此外,您最好将 stamper = PdfStamper.createSignature(reader,new FileOutputStream(dest), '\0', null, true);
[...]
stamper.close();
}//for
置于变量中,并在关闭new FileOutputStream(dest)
stamper:
当然,请遵循Bruno的建议,阅读他的PDF签名白皮书,并更新您的签名创建代码,以生成非弃用类型的签名。
答案 1 :(得分:0)
我看到方法setCrypto()
,这意味着你没有使用最新版本的iText;我还看到了选项PdfSignatureAppearance.SELF_SIGNED
,这意味着您正在创建一个不符合当今标准的签名。
请你自己帮个忙看看documentation?
另外:您使用的是与源和目标相同的文件?这不可能。您至少需要创建一个临时文件或在内存中创建该文件,然后覆盖现有文件。