【发布时间】:2015-01-26 11:34:54
【问题描述】:
我正在动态创建 PDF 文档,添加签名字段,然后尝试对其进行签名。签名工作正常,但我得到一个例外:
"% 认证,无效签名和签名包含无效数据"
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.util.Calendar;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.security.BouncyCastleDigest;
import com.itextpdf.text.pdf.security.ExternalDigest;
import com.itextpdf.text.pdf.security.ExternalSignature;
import com.itextpdf.text.pdf.security.MakeSignature;
import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard;
import com.itextpdf.text.pdf.security.PrivateKeySignature;
//Actual class
public class SignPdf {
// Signs the pdf
public void signPdf(String src, String dest, boolean certified, boolean graphic) throws GeneralSecurityException, IOException, DocumentException{
String path = "src/certs.pfx";
String keystore_password = "pwd";
String key_password = "pwd";
KeyStore ks = KeyStore.getInstance("PKCS12", new org.bouncycastle.jce.provider.BouncyCastleProvider());
InputStream is = this.getClass().getResourceAsStream("/certs.pfx");
ks.load(is, keystore_password.toCharArray());
String alias = ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, key_password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
byte[] pdfByteArray = null;
// creating dynamic document using itext.
Document document = new Document();
OutputStream baosPDF = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baosPDF);
document.open();
document.add(new Paragraph("Hello World!"));
document.close();
byte[] bytearrayb = ((ByteArrayOutputStream) baosPDF).toByteArray();
PdfReader reader = new PdfReader(bytearrayb);
PdfStamper stamper = PdfStamper.createSignature(reader, baosPDF, '\0', null, true);
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason("Security");
appearance.setLocation("Footer");
appearance.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, "DVA");
if (certified) appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
if (graphic) {
appearance.setSignatureGraphic(Image.getInstance(RESOURCE));
appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
}
appearance.setSignDate(Calendar.getInstance());
appearance.setSignatureCreator("test");
ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "BC");
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, es, chain, null, null, null, 0, CryptoStandard.CMS);
baosPDF.flush();
baosPDF.close();
BufferedOutputStream fs = new BufferedOutputStream(new FileOutputStream(new File("myFile121.pdf")));
fs.write(((ByteArrayOutputStream) baosPDF).toByteArray());
fs.flush();
fs.close();
}
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
SignPdf signatures = new SignPdf();
try {
signatures.signPdf(ORIGINAL, "", true, false);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
【问题讨论】:
-
它的签名正确,但我得到一个异常“% 认证,无效签名和签名包含无效数据”
-
您正在将较新版本的 iText (
import com.itextpdf) 与过时版本的 iText (import com.lowagie) 混合使用。请仅使用较新版本的 iText。由于您对库的使用不一致,可能会发生许多不可预知的错误。这使您的问题无法回答。 -
非常感谢。这次我使用了正确的导入(com.itextpdf.Document,Paragraph,PDFwrite)。我删除了旧版本的 jar。它现在编译成功,但是当我执行它时,我得到了同样的异常。
-
请清理您的问题。确保代码显示良好(使用正确的缩进)并将实际问题从您的评论移到问题的正文。阅读您的问题非常困难。让人眼前一亮的一件事是,您可以重用
baosPDF而无需重新初始化ByteArrayOutputStream。这看起来是个非常糟糕的主意。
标签: pdf itext digital-signature itextpdf