使用iText和证书对pdf签名,也可使用USB硬件
PdfReader reader = new PdfReader("d:\\work\\project\\sign\\test.pdf"); FileOutputStream fout = new FileOutputStream("d:\\work\\project\\sign\\test2.pdf"); PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', null,true);
PdfReader reader = new PdfReader("d:\\work\\project\\sign\\test.pdf"); FileOutputStream fout = new FileOutputStream("d:\\work\\project\\sign\\test2.pdf"); PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', null,true); PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
sap.setVisibleSignature(new Rectangle(60, 100, 773, 231), 1,"SignatureField1");
// sap.setAcro6Layers(true);
sap.setSignatureGraphic(Image.getInstance("d:\\work\\project\\sign\\title.jpg"));
sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));
dic.setReason(sap.getReason());
dic.setLocation(sap.getLocation());
dic.setContact(sap.getContact());
dic.setDate(new PdfDate(sap.getSignDate()));
sap.setCryptoDictionary(dic);
int contentEstimated = 7000;
HashMap
exc.put(PdfName.CONTENTS, new Integer(contentEstimated * 2 + 2));
sap.setReason("this is the reason");
sap.setLocation("this is the location");
sap.preClose(exc);
InputStream data = sap.getRangeStream();
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
byte buf[] = new byte[8192];
int n;
while ((n = data.read(buf)) > 0) {
messageDigest.update(buf, 0, n);
}
byte hash[] = messageDigest.digest();
Calendar cal = Calendar.getInstance();
//这里的chain为公钥的证书链
PdfPKCS7 pk7 = new PdfPKCS7(null, chain, "SHA1", null, null, false);
byte[] sh = pk7.getAuthenticatedAttributeBytes(hash, cal, null, null,
null);
// 这里的sign(sh)为签名后的数据,可以将sh传给USB获取签名,网上都是获取私钥传给iText然后对pdf签名,这种只适合文件证书,如果针对USB硬件或密码机就必须按照此文档,研究iText的源码才发现,
pk7.setExternalDigest(sign(sh), null, "RSA");
byte[] sg = pk7.getEncodedPKCS7(hash, cal);
if (contentEstimated + 2 < sg.length)
throw new DocumentException("Not enough space");
byte[] paddedSig = new byte[contentEstimated];
System.arraycopy(sg, 0, paddedSig, 0, sg.length);
PdfDictionary dic2 = new PdfDictionary();
dic2.put(PdfName.CONTENTS, new PdfString(paddedSig) .setHexWriting(true));
sap.close(dic2);