记录一下使用iText5组件进行pdf文字或图片签章
库文件:bcmail-jdk14-1.38.jar, bcpkix-jdk15on-1.54.jar, bcprov-jdk14-1.38.jar, bcprov-jdk15on-1.54.jar,itext-asian-5.2.0.jar,itextpdf-5.5.12.jar
输入:自建的PDF文件、pkcs12密钥证书、自定义签章图片、自定义文字信息、外部字体
输出:签章后的PDF文件
用途:PDF浏览器可以识别该文件在Signature之后是否被修改过
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream("D:/ex/pdfsign2.p12"), "123456".toCharArray());//STOREPASS,密钥库
String alias = ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias,"123456".toCharArray() );//KEYPASS ,私钥
Certificate[] cer = ks.getCertificateChain(alias); //证书
PdfReader read = new PdfReader("d:/ex/test2.pdf");
FileOutputStream os = new FileOutputStream("d:/ex/test2_sig.pdf");
PdfStamper pstp = PdfStamper.createSignature(read, os, '\0', null, true);//签证工具类对象,true表示可以反复签章(详见http://itextsupport.com/apidocs/itext5)
PdfSignatureAppearance psa = pstp.getSignatureAppearance(); //签章属性对象
Image img = Image.getInstance("D:\\0001_ICONS\\bee.jpg");
psa.setSignatureGraphic(img); //签章图片
psa.setReason("Private Reason[个人原因]");
psa.setLocation("太阳系地球北半球东经120°");
psa.setVisibleSignature(new Rectangle(180, 100, 650, 170),1,"sigflag1");
psa.setSignDate(Calendar.getInstance());
psa.setRenderingMode(RenderingMode.GRAPHIC_AND_DESCRIPTION);
psa.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);
BaseFont f3 = BaseFont.createFont("fonts/MSYH.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);//外部字体
//BaseFont f = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
psa.setLayer2Font(new Font(f3,10,Font.NORMAL,BaseColor.BLUE));
ExternalDigest dg = new BouncyCastleDigest(); //摘要算法
ExternalSignature es = new PrivateKeySignature(pk,DigestAlgorithms.SHA1,null);//签名算法
MakeSignature.signDetached(psa, dg, es, cer, null, null, null, 0, CryptoStandard.CMS);//签章
JOptionPane.showMessageDialog(null, "完成!");
/**
* 密钥建立
* keytool -genkey -v -alias merrickpdfsign2 -keyalg RSA -storetype PKCS12 -keystore D:/ex/pdfsign2.p12 -storepass 123456 -keypass 123456
* */