【itext学习之路】--5.对pdf进行盖章/签章/数字签名

来源:【itext学习之路】-------(第五篇)对pdf进行盖章/签章/数字签名_tomatocc的博客-CSDN博客_itext 数字签名

在上一篇文章中,我们学习了使用itext对pdf增加图片水印和文本水印,那么这篇文章我们将要学习更高级一点的水印----印章。可能你会有疑问,印章不也是一个图片吗?当然,你可以把一个印章图片来做成图片水印,但是我们这里要介绍的是,通过数字签名的方式来进行pdf签章。

首选,我们要准备好jar包。

bcpkix-jdk15on-1.49.jar
bcprov-jdk15on-1.49.jar
itext-asian-5.2.0.jar
itextpdf-5.5.11-sources.jar
itextpdf-5.5.11.jar

大家可以去maven库中进行下载,也可以直接下载我上传的jar包文件:点击下载

下载好jar包之后,我们还要去了解一门技术:数字证书,而在本文中,我们需要生成一个.p12结尾的数字证书,该证书用来对我们的pdf文档进行数字签名。生成.p12证书的方法请参考我的另一篇文章:使用JDK的keytool生成p12证书

直到这里,我们前期的准备工作就已经全部做好,接下来,我们就要步入正题:对pdf进行签章。

  • 首先,我们创建一个SignatureInfo的实体类,用途是为了方便的增加需要签章的信息:
package cn.tomtocc.pdf;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import java.security.PrivateKey;
import java.security.cert.Certificate;public class SignatureInfo {private  String reason; //签名的原因,显示在pdf签名属性中private  String location;//签名的地点,显示在pdf签名属性中private String digestAlgorithm;//摘要算法名称,例如SHA-1private String imagePath;//图章路径private  String fieldName;//表单域名称private  Certificate[] chain;//证书链private  PrivateKey pk;//签名私钥private  int certificationLevel = 0; //批准签章private PdfSignatureAppearance.RenderingMode renderingMode;//表现形式:仅描述,仅图片,图片和描述,签章者和描述//图章属性private float rectllx ;//图章左下角xprivate float rectlly ;//图章左下角yprivate float recturx ;//图章右上角xprivate float rectury ;//图章右上角ypublic float getRectllx() {return rectllx;}public void setRectllx(float rectllx) {this.rectllx = rectllx;}public float getRectlly() {return rectlly;}public void setRectlly(float rectlly) {this.rectlly = rectlly;}public float getRecturx() {return recturx;}public void setRecturx(float recturx) {this.recturx = recturx;}public float getRectury() {return rectury;}public void setRectury(float rectury) {this.rectury = rectury;}public String getReason() {return reason;}public void setReason(String reason) {this.reason = reason;}public String getLocation() {return location;}public void setLocation(String location) {this.location = location;}public String getDigestAlgorithm() {return digestAlgorithm;}public void setDigestAlgorithm(String digestAlgorithm) {this.digestAlgorithm = digestAlgorithm;}public String getImagePath() {return imagePath;}public void setImagePath(String imagePath) {this.imagePath = imagePath;}public String getFieldName() {return fieldName;}public void setFieldName(String fieldName) {this.fieldName = fieldName;}public Certificate[] getChain() {return chain;}public void setChain(Certificate[] chain) {this.chain = chain;}public PrivateKey getPk() {return pk;}public void setPk(PrivateKey pk) {this.pk = pk;}public int getCertificationLevel() {return certificationLevel;}public void setCertificationLevel(int certificationLevel) {this.certificationLevel = certificationLevel;}public PdfSignatureAppearance.RenderingMode getRenderingMode() {return renderingMode;}public void setRenderingMode(PdfSignatureAppearance.RenderingMode renderingMode) {this.renderingMode = renderingMode;}}
  • 第二步,我们创建一个用于对pdf签章的工具类,以及main方法
package cn.tomtocc.pdf;import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
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.security.BouncyCastleDigest;
import com.itextpdf.text.pdf.security.DigestAlgorithms;
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.PrivateKeySignature;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;public class ItextUtil {public static final char[] PASSWORD = "123456".toCharArray();// keystory密码/*** 单多次签章通用* * @param src* @param target* @param signatureInfos* @throws GeneralSecurityException* @throws IOException* @throws DocumentException*/@SuppressWarnings("resource")public void sign(String src, String target, SignatureInfo signatureInfo) {InputStream inputStream = null;FileOutputStream outputStream = null;ByteArrayOutputStream result = new ByteArrayOutputStream();try {inputStream = new FileInputStream(src);ByteArrayOutputStream tempArrayOutputStream = new ByteArrayOutputStream();PdfReader reader = new PdfReader(inputStream);// 创建签章工具PdfStamper ,最后一个boolean参数是否允许被追加签名// false的话,pdf文件只允许被签名一次,多次签名,最后一次有效// true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改PdfStamper stamper = PdfStamper.createSignature(reader,tempArrayOutputStream, '\0', null, true);// 获取数字签章属性对象PdfSignatureAppearance appearance = stamper.getSignatureAppearance();appearance.setReason(signatureInfo.getReason());appearance.setLocation(signatureInfo.getLocation());// 设置签名的位置,页码,签名域名称,多次追加签名的时候,签名预名称不能一样 图片大小受表单域大小影响(过小导致压缩)// 签名的位置,是图章相对于pdf页面的位置坐标,原点为pdf页面左下角// 四个参数的分别是,图章左下角x,图章左下角y,图章右上角x,图章右上角yappearance.setVisibleSignature(new Rectangle(signatureInfo.getRectllx(), signatureInfo.getRectlly(), signatureInfo.getRecturx(),signatureInfo.getRectury()), 1, signatureInfo.getFieldName());// 读取图章图片Image image = Image.getInstance(signatureInfo.getImagePath());appearance.setSignatureGraphic(image);appearance.setCertificationLevel(signatureInfo.getCertificationLevel());// 设置图章的显示方式,如下选择的是只显示图章(还有其他的模式,可以图章和签名描述一同显示)appearance.setRenderingMode(signatureInfo.getRenderingMode());// 摘要算法ExternalDigest digest = new BouncyCastleDigest();// 签名算法ExternalSignature signature = new PrivateKeySignature(signatureInfo.getPk(), signatureInfo.getDigestAlgorithm(),null);// 调用itext签名方法完成pdf签章 //数字签名格式,CMS,CADEMakeSignature.signDetached(appearance, digest, signature,signatureInfo.getChain(), null, null, null, 0,MakeSignature.CryptoStandard.CADES);inputStream = new ByteArrayInputStream(tempArrayOutputStream.toByteArray());// 定义输入流为生成的输出流内容,以完成多次签章的过程result = tempArrayOutputStream;outputStream = new FileOutputStream(new File(target));outputStream.write(result.toByteArray());outputStream.flush();} catch (Exception e) {e.printStackTrace();} finally {try {if (null != outputStream) {outputStream.close();}if (null != inputStream) {inputStream.close();}if (null != result) {result.close();}} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) {try {ItextUtil app = new ItextUtil();// 将证书文件放入指定路径,并读取keystore ,获得私钥和证书链String pkPath = "D:/server.p12";KeyStore ks = KeyStore.getInstance("PKCS12");ks.load(new FileInputStream(pkPath), PASSWORD);String alias = ks.aliases().nextElement();PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD);// 得到证书链Certificate[] chain = ks.getCertificateChain(alias);//需要进行签章的pdfString path = "D:/demo.pdf";// 封装签章信息SignatureInfo signInfo = new SignatureInfo();signInfo.setReason("理由");signInfo.setLocation("位置");signInfo.setPk(pk);signInfo.setChain(chain);signInfo.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);signInfo.setDigestAlgorithm(DigestAlgorithms.SHA1);signInfo.setFieldName("demo");// 签章图片signInfo.setImagePath("d:/sign.jpg");signInfo.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);signInfo.setRectllx(100);  // 值越大,代表向x轴坐标平移 缩小 (反之,值越小,印章会放大)signInfo.setRectlly(200);  // 值越大,代表向y轴坐标向上平移(大小不变)signInfo.setRecturx(400);  // 值越大   代表向x轴坐标向右平移  (大小不变)signInfo.setRectury(100);  // 值越大,代表向y轴坐标向上平移(大小不变)//签章后的pdf路径app.sign(path, "D:/demo3.pdf", signInfo);} catch (Exception e) {e.printStackTrace();}}
}

为了方便各位理解,这里我将d盘所用到的文件在这里截图展示。

 

  • 然后我们打开demo3.pdf,就可以看到pdf中已经有一个印章了,如果各位对上面代码中的一些参数不是很了解,欢迎留言交流。

在这里插入图片描述

点击下载《ITEXT官方英文API+中文使用说明》 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/496230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python selenium 用法 和 Chrome headless

From: http://cuiqingcai.com/2599.html Selenium教程:https://www.yiibai.com/selenium selenium 官方参考文档:https://selenium-python.readthedocs.io/index.html Selenium Documentation:https://www.seleniumhq.org/docs Selenium 与 …

【itext学习之路】--1.创建一个简单的pdf文档

来源:https://blog.csdn.net/tomatocc/article/details/80666011 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件 本教程中…

并发服务器设计思路,参考apache学习UDP和QoS,研究成果

研究了快1个月的服务器架构,把研究成果记录一下。参考的有:Apache vlc ACE ftp我主要需要其中的并发处理,内存管理,TCP/UDP.QoS,速度限制等方面的内容,所以着重说这几方面。首先看一下Apache的基本框图&…

一文看懂NB-IoT!

来源:物联江湖(iot521) 作者:王一鸣一直以来,人们通过相应的终端(电脑、手机、平板等)使用网络服务,“个人”一直是网络的用户主体。个人对网络质量的要求“高”且“统一”:玩网络游戏必需要低…

安装、配置 Java JDK 和 JRE,并卸载自带 OpenJDK

JRE 和 JDK 的区别是什么?:https://www.zhihu.com/question/20317448 如何配置 Java 环境变量:https://jingyan.baidu.com/article/fd8044fa2c22f15031137a2a.html Windows 10 配置Java 环境变量:https://www.runoob.com/w3cnote…

将十进制数转为N进制的方法

设有一个数 A,比如 A15 ,转为四进制数应当表示为33.原理如下:1.A除N,2.A模N.3.保存A模N的值。4.循环1&#xff0c;2。直到 A除N的值等于0;Codeclass NumerationConverter { /// <summary> /// 将十进制度数转为四进制 /// </summary> …

人工智能即将冲击与改变现有的医疗方式

来源呢&#xff1a;千家网从1960年代初&#xff0c;学术界陆续展开对于人工智能的研究&#xff0c;一直到目前的机器学习、深度学习等观念&#xff0c;所带来的第三波人工智能浪潮。对于医疗领域来说&#xff0c;在1970年代初期&#xff0c;人工智能就已经被应用在各项检查&…

【itext学习之路】--2.设置pdf的一些常用属性

来源&#xff1a;https://blog.csdn.net/tomatocc/article/details/80666361 在上一篇文章中&#xff0c;我们已经成功的创建了一个简单的pdf&#xff0c;下面我将学习设置该pdf的常用属性&#xff0c;其中包括&#xff1a;作者&#xff0c;创建时间&#xff0c;pdf创建者&…

简单好用的 Linux/Windows 面板

简单好用的 Linux/Windows 面板宝塔官网&#xff1a;https://www.bt.cn 宝塔Linux面板新手安装教程&#xff1a;https://www.cnblogs.com/paul8339/p/7065799.html https://blog.csdn.net/letterss/article/details/80216091 宝塔面板手册截图&#xff08;地址&#xff1a;http…

任正非:中美领跑AI说法不合适、5G被炒作过热……

来源&#xff1a;羊城晚报 作者&#xff1a;宋毅摘要&#xff1a;2017年&#xff0c;华为又交出漂亮答卷&#xff1a;实现全球销售收入6036亿元&#xff0c;同比增长15.7%。4日&#xff0c;任正非接受了羊城晚报等5家媒体的采访&#xff0c;谈到了华为每年15%的研发投入&#…

【itext学习之路】--3.对pdf文档进行加密和权限设置

来源&#xff1a;https://blog.csdn.net/tomatocc/article/details/80667838 上篇文章&#xff0c;我们学习了pdf的属性设置&#xff0c;但是我们知道&#xff0c;在实际开发中&#xff0c;如果pdf文档被黑客盗取的话&#xff0c;那么pdf中的信息就会被泄露&#xff0c;因此本…

scrapy 模拟登陆

python 模拟登录豆瓣 并 发表动态&#xff1a;https://blog.csdn.net/freeking101/article/details/65445551 python网络爬虫之使用scrapy自动登录网站&#xff1a;https://www.cnblogs.com/zhanghongfeng/p/7684415.html Scrapy笔记&#xff08;11&#xff09;- 模拟登录&am…

李国杰院士等:未来移动通信系统中的通信与计算融合

来源 5G 作者&#xff1a;周一青 李国杰周一青&#xff1a;中国科学院大学教授&#xff0c;中国科学院计算技术研究所“百人计划”研究员、博导&#xff0c;无线通信技术研究中心副主任&#xff0c;移动计算与新型终端北京市重点实验室研究员。李国杰&#xff1a;中国工程院院…

【itext学习之路】--4.给pdf增加文本水印和图片水印

来源&#xff1a;【itext学习之路】-------&#xff08;第四篇&#xff09;给pdf增加文本水印和图片水印_tomatocc的博客-CSDN博客_itext添加水印 一般而言&#xff0c;许多公司在做pdf之后&#xff0c;都会将公司的logo或者网址以水印的方式添加到pdf文件中。本篇文章&#x…

Postman 使用方法详解

From&#xff1a;https://blog.csdn.net/fxbin123/article/details/80428216 Postman使用详解&#xff1a;https://www.cnblogs.com/xiaoxi-3-/p/7839278.html Postman用法简介&#xff1a;https://blog.csdn.net/flowerspring/article/details/52774399 Postman 详解&#xff…

基于互联网大脑架构的腾讯未来趋势分析[系列1]

作者&#xff1a;刘锋&#xff0c;计算机博士 《互联网进化论》前言互联网大脑架构不是人为规划出来的&#xff0c;而是过去50年&#xff0c;互联网在科学探索和商业竞争两大动力推动下&#xff0c;形成的类脑架构。它的提出是基于2008年以来&#xff0c;我们对移动互联网&…

Linux看内存标压低压,三代锐龙、国产Linux上身笔记本电脑,性能是否和参数一样好看?...

原标题&#xff1a;三代锐龙、国产Linux上身笔记本电脑&#xff0c;性能是否和参数一样好看&#xff1f;如果你从很早开始就关注电脑行业&#xff0c;基本上你身边的朋友都会告诫你一句&#xff1a;“笔记本电脑千万别买AMD的……”并不是AMD不好&#xff0c;说实话&#xff0c…

Windows 安装 MongoDB 和 可视化工具Robo3T

MongoDB 官网下载地址&#xff1a;https://www.mongodb.com/try/download/community MongoDB 是一款非常热门的 NoSQL 面向文档的数据库管理系统&#xff0c; 分为 企业版收费版 和 社区免费版。MongoDB 使用 BSON 对象来存储&#xff0c;与 JSON 格式类型的 "键 - 值&quo…

量子计算生态:市场预期、行业应用与“霸权”争夺

来源&#xff1a;资本实验室从IBM宣布推出业界首个商用量子计算系统&#xff0c;到我国开通全球首条量子通信干线并成功实现首次洲际量子通信&#xff0c;2017年的量子计算领域精彩不断&#xff0c;并不断提升市场对量子计算的预期。除了应用于国防安全&#xff0c;在科研、医疗…

xhtmlrenderer + iText-HTML转PDF

来源&#xff1a;xhtmlrenderer iText-HTML转PDF_hunan961的博客-CSDN博客_xhtmlrenderer xhtmlrendereitext2.0.8 将html转成pdf&#xff0c;带样式、图片(也支持二维码、条形码)等 主要步骤 生成html&#xff08;css样式直接放在style中&#xff09;html转换pdf方法数据返…