本文记录iText7实现PDF电子签章
提前准备
1、keystore文件,生成自签名证书,猛戳:SpringBoot系列——启用https
打开cmd,执行以下命令 keytool -genkeypair -alias stamper -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore e:/Java/stamper.keystore -storepass 123456
2、印章图片,这里有个在线制作电子公章小工具:http://makepic.net/tool/signet.html
3、pom需要引入新依赖包
<!-- 条形码、电子签章 --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>barcodes</artifactId> <version>${itext7.version}</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>hyph</artifactId> <version>${itext7.version}</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>font-asian</artifactId> <version>${itext7.version}</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>sign</artifactId> <version>${itext7.version}</version> </dependency> <!-- 加密软件包 --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.69</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.69</version> </dependency>
代码
/** * 电子签章 * @param src 需要签章的pdf文件路径 * @param dest 签完章的pdf文件路径 */ public static void sign(String src, String dest) { final String KEYSTORE = "E:\\Java\\stamper.keystore";//keystore文件路径 final char[] PASSWORD = "123456".toCharArray();// keystore密码 final String STAMPER_SRC = "E:\\Java\\stamper.gif";//印章图片路径 try (PdfReader reader = new PdfReader(src); FileOutputStream os = new FileOutputStream(dest);){ //读取keystore ,获得私钥和证书链 jks KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(KEYSTORE), PASSWORD); String alias = ks.aliases().nextElement(); PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD); Certificate[] chain = ks.getCertificateChain(alias); //创建签章工具PdfSigner、设定数字签章的属性 PdfSigner stamper = new PdfSigner(reader, os, new StampingProperties()); PdfSignatureAppearance appearance = stamper.getSignatureAppearance(); appearance.setReason("签名原因:系统自动签名盖章"); appearance.setLocation("签名地点:xxx系统"); appearance.setContact("联系方式:huanzi.qch@qq.com"); //加盖图章图片 ImageData img = ImageDataFactory.create(STAMPER_SRC); Image image = new Image(img); appearance.setPageNumber(1); appearance.setPageRect(new Rectangle(650, 50, image.getImageWidth(), image.getImageHeight())); appearance.setSignatureGraphic(img); appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC); //No such provider: BC : 问题解决,加BC库支持 Security.addProvider(new BouncyCastleProvider()); //摘要算法 IExternalDigest digest = new BouncyCastleDigest(); //签名算法 IExternalSignature signature = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, BouncyCastleProvider.PROVIDER_NAME); //调用itext签名方法完成pdf签章 stamper.setCertificationLevel(1); stamper.signDetached(digest,signature, chain, null, null, null, 0, PdfSigner.CryptoStandard.CMS); System.out.println("操作完成!"); }catch (Exception e){ e.printStackTrace(); System.err.println("操作异常..."); } }
效果
我们用 test() 生成的简单PDF文件来进行电子签章测试
//测试 public static void main(String[] args) { //test(); //html2pdf(); sign("E:\\Java\\test.pdf","E:\\Java\\test2.pdf"); }