准备工作

需要引用aspose包,引入操作我写了一个博客,地址如下

https://blog.csdn.net/weixin_46713508/article/details/125495770?spm=1001.2014.3001.5502

PDF实现CA签名认证也写过,地址如下

https://blog.csdn.net/weixin_46713508/article/details/125660108?spm=1001.2014.3001.5501

引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.test</groupId><artifactId>aspose-word-excel</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>com.aspose.words</groupId><artifactId>aspose-words</artifactId><version>words-15.8.0-jdk16</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar</systemPath></dependency><dependency><groupId>com.aspose.cells</groupId><artifactId>aspose-cells</artifactId><version>cell-8.5.2</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/aspose-cells-8.5.2.jar</systemPath></dependency><dependency><groupId>com.aspose.pdf</groupId><artifactId>aspose-pdf</artifactId><version>pdf-17.3.0</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/aspose.pdf-17.3.0.jar</systemPath></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version><scope>compile</scope></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.10</version></dependency><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.14.0</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcpkix-jdk15on</artifactId><version>1.60</version></dependency></dependencies><repositories><repository><id>com.e-iceblue</id><url>https://repo.e-iceblue.cn/repository/maven-public/</url></repository></repositories></project>

然后是CA签名方法

package dmyz.util;import com.aspose.words.License;
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.*;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.Certificate;public class PdfAppendSealUtil {/*** 获取license** @return*/public static boolean getLicense() {boolean result = false;try {InputStream is = PdfAppendSealUtil.class.getClassLoader().getResourceAsStream("\\license.xml");License aposeLic = new License();aposeLic.setLicense(is);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/**** @param src 需要签章的pdf文件路径* @param dest 签完章的pdf文件路径* @param chain 证书链* @param img 印章图片* @param pk 签名私钥* @param digestAlgorithm 摘要算法名称,例如SHA-1* @param provider  密钥算法提供者,可以为null* @param subfilter 数字签名格式,itext有2种* @param reason 签名的原因,显示在pdf签名属性中* @param location 签名的地点,显示在pdf签名属性中* @throws GeneralSecurityException* @throws IOException* @throws DocumentException*/public static void sign(String src, String dest, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm, String provider,MakeSignature.CryptoStandard subfilter, String reason, String location,int page) throws GeneralSecurityException, IOException, DocumentException {// 验证Licenseif (!PdfAppendSealUtil.getLicense()) {return;}PdfReader pdfReader = new PdfReader(src);FileOutputStream fileOutputStream = new FileOutputStream(dest);/*** 1 参数依次为:文件名、文件输入流、文件版本号、临时文件、是否可以追加签名*  1.1 false的话,pdf文件只允许被签名一次,多次签名,最后一次有效*  1.2 true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改*/PdfStamper stamper = PdfStamper.createSignature(pdfReader, fileOutputStream, '\0', null, true);// 获取数字签章属性对象,设定数字签章的属性PdfSignatureAppearance appearance = stamper.getSignatureAppearance();appearance.setReason(reason);appearance.setLocation(location);/*** 1 三个参数依次为:设置签名的位置、页码、签名域名称,多次追加签名的时候,签名域名称不能一样*  1.1 签名的位置四个参数:印章左下角的X、Y轴坐标,印章右上角的X、Y轴坐标,*      这个位置是相对于PDF页面的位置坐标,即该坐标距PDF当前页左下角的坐标*/appearance.setVisibleSignature(new Rectangle(547, 450, 617, 600), page, "sign"+page);/*** 用于盖章的印章图片,引包的时候要引入itext包的image*/Image image = Image.getInstance(img);appearance.setSignatureGraphic(image);/*** 设置认证等级,共4种,分别为:*  NOT_CERTIFIED、CERTIFIED_NO_CHANGES_ALLOWED、*  CERTIFIED_FORM_FILLING 和 CERTIFIED_FORM_FILLING_AND_ANNOTATIONS** 需要用哪一种根据业务流程自行选择*/appearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);/*** 印章的渲染方式,同样有4种:*  DESCRIPTION、NAME_AND_DESCRIPTION,*  GRAPHIC_AND_DESCRIPTION,GRAPHIC;* 这里选择只显示印章*/appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);/*** 算法主要为:RSA、DSA、ECDSA* 摘要算法,这里的itext提供了2个用于签名的接口,可以自己实现*/ExternalDigest digest = new BouncyCastleDigest();/*** 签名算法,参数依次为:证书秘钥、摘要算法名称,例如MD5 | SHA-1 | SHA-2.... 以及 提供者*/ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, null);/*** 调用itext签名方法完成pdf签章*/MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter);fileOutputStream.close();}}

最后是测试类

package dmyz.util;import com.aspose.words.License;
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.*;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.Certificate;public class PdfAppendSealUtil {/*** 获取license** @return*/public static boolean getLicense() {boolean result = false;try {InputStream is = PdfAppendSealUtil.class.getClassLoader().getResourceAsStream("\\license.xml");License aposeLic = new License();aposeLic.setLicense(is);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/**** @param src 需要签章的pdf文件路径* @param dest 签完章的pdf文件路径* @param chain 证书链* @param img 印章图片* @param pk 签名私钥* @param digestAlgorithm 摘要算法名称,例如SHA-1* @param provider  密钥算法提供者,可以为null* @param subfilter 数字签名格式,itext有2种* @param reason 签名的原因,显示在pdf签名属性中* @param location 签名的地点,显示在pdf签名属性中* @throws GeneralSecurityException* @throws IOException* @throws DocumentException*/public static void sign(String src, String dest, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm, String provider,MakeSignature.CryptoStandard subfilter, String reason, String location,int page) throws GeneralSecurityException, IOException, DocumentException {// 验证Licenseif (!PdfAppendSealUtil.getLicense()) {return;}PdfReader pdfReader = new PdfReader(src);FileOutputStream fileOutputStream = new FileOutputStream(dest);/*** 1 参数依次为:文件名、文件输入流、文件版本号、临时文件、是否可以追加签名*  1.1 false的话,pdf文件只允许被签名一次,多次签名,最后一次有效*  1.2 true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改*/PdfStamper stamper = PdfStamper.createSignature(pdfReader, fileOutputStream, '\0', null, true);// 获取数字签章属性对象,设定数字签章的属性PdfSignatureAppearance appearance = stamper.getSignatureAppearance();appearance.setReason(reason);appearance.setLocation(location);/*** 1 三个参数依次为:设置签名的位置、页码、签名域名称,多次追加签名的时候,签名域名称不能一样*  1.1 签名的位置四个参数:印章左下角的X、Y轴坐标,印章右上角的X、Y轴坐标,*      这个位置是相对于PDF页面的位置坐标,即该坐标距PDF当前页左下角的坐标*/appearance.setVisibleSignature(new Rectangle(547, 450, 617, 600), page, "sign"+page);/*** 用于盖章的印章图片,引包的时候要引入itext包的image*/Image image = Image.getInstance(img);appearance.setSignatureGraphic(image);/*** 设置认证等级,共4种,分别为:*  NOT_CERTIFIED、CERTIFIED_NO_CHANGES_ALLOWED、*  CERTIFIED_FORM_FILLING 和 CERTIFIED_FORM_FILLING_AND_ANNOTATIONS** 需要用哪一种根据业务流程自行选择*/appearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);/*** 印章的渲染方式,同样有4种:*  DESCRIPTION、NAME_AND_DESCRIPTION,*  GRAPHIC_AND_DESCRIPTION,GRAPHIC;* 这里选择只显示印章*/appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);/*** 算法主要为:RSA、DSA、ECDSA* 摘要算法,这里的itext提供了2个用于签名的接口,可以自己实现*/ExternalDigest digest = new BouncyCastleDigest();/*** 签名算法,参数依次为:证书秘钥、摘要算法名称,例如MD5 | SHA-1 | SHA-2.... 以及 提供者*/ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, null);/*** 调用itext签名方法完成pdf签章*/MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter);fileOutputStream.close();}}

项目目录如下

直接运行即可

这样就生成了

这种方式效率比较低,每次会生成无用的文件,把他们累加在一起得到最终的结果,后面会研究下其他方法

Java生成骑缝章带有CA电子签名认证相关推荐

  1. Java给PDF文件生成骑缝章

    什么是缝骑章? 骑缝章(Paging seal.)是海关常用词汇.为了保证海关监管货物留存单据的完整齐全以及核对有关单证,在单据交接处所加盖的印章. 在两张纸交接处的印章.这种印章多盖在条据.证书或其 ...

  2. MATLAB生成骑缝章(png to png)

    好家伙,为了一个水课作业,找了一个下午的免费骑缝章程序,不是不能用就是加水印,一气之下干脆用MATLAB写了个. 本程序仅支持为png批量添加来自png的骑缝章,输出也是png. 先放代码,再放使用说 ...

  3. JAVA通过itextpdf实现PDF骑缝章

    先引入pom引入jar包 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf ...

  4. Java生成名片式的二维码源码分享

    世界上25%的人都有拖延症--但我觉得这统计肯定少了,至少我就是一名拖延症患者.一直想把"Java生成名片式(带有背景图片.用户网络头像.用户昵称)的二维码"这篇博客分享出来,但一 ...

  5. CA双向认证完整实现步骤(附java客户端代码)

    一.基础概念 注:以下概念除专业名词外,均为个人理解,不具备权威性. 1.什么是系统安全管理 置于公网的系统,通常都需要一定的安全管理,据我个人理解,这里的安全管理主要分三个方面: 一是应用内的权限控 ...

  6. ssl证书CA双向认证完整实现步骤(附java客户端代码)(好文章!)

    一.基础概念 注:以下概念除专业名词外,均为个人理解,不具备权威性. 1.什么是系统安全管理 置于公网的系统,通常都需要一定的安全管理,据我个人理解,这里的安全管理主要分三个方面: 一是应用内的权限控 ...

  7. Java 中pdf部分内容加边线_Java 在PDF中添加骑缝章示例解析

    骑缝章是用于往来业务合同,以确保合同真实.有效的印章加盖方法,是一种防范风险的重要方式.在Java程序中,可以通过使用工具来辅助加盖这种骑缝章. 工具:Free Spire.PDF for Java ...

  8. java maven 读写pdf_Java 在PDF中加盖骑缝章

    骑缝章是用于往来业务合同,以确保合同真实.有效的印章加盖方法,是一种防范风险的重要方式.在Java程序中,可以通过使用工具来辅助加盖这种骑缝章. 工具:Free Spire.PDF for Java ...

  9. Java 在PDF中添加骑缝章

    骑缝章是用于往来业务合同,以确保合同真实.有效的印章加盖方法,是一种防范风险的重要方式.在Java程序中,可以通过使用工具来辅助加盖这种骑缝章. 工具:Free Spire.PDF for Java ...

最新文章

  1. (拆点+最小路径覆盖) bzoj 2150
  2. oledb 访问接口sqlncli10返回了消息 没有活动事务_这样理解分布式事务你是不是就会懂了?...
  3. Oracle 11gR2 RAC 中的 Grid Plug and Play(GPnP) 是什么?
  4. 2016年系统集成项目管理工程师最新考试说明
  5. linux mdel 命令详解
  6. Altium Designer(一):SCH
  7. mysql常用语句1
  8. VB6 Socket编程
  9. FP-XH 松下PLC控制器资料下载
  10. 用flash做古诗动画_《古诗三首》Flash动画课件
  11. SIM900A—基础指令
  12. 嗨到起飞!终于搞懂前端数据可视化了!
  13. bzoj4816 [Sdoi2017]数字表格(反演)
  14. 正则校验18位身份证号,拿走即用!
  15. python绘制地图地图cartopy_python Cartopy的基础使用详解
  16. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十四) Be careful!前方怪物出没...
  17. 《城市大脑系列建设标准规范》立项评审会胜利召开
  18. 傲游 android 2.3,傲游浏览器安卓版-傲游浏览器手机版v5.2.3.3256-3454手机软件
  19. jsp text边框_CSS设置DIV边框实例
  20. 区块链技术十周年—回眸与前瞻

热门文章

  1. swapidc不能连接到主机_SWAPIDC完整对接EP主机分销教程
  2. 服务端thrift 使用非阻塞式IO报异常Got an IOException in internalRead!
  3. pyecharts0.5.x制作含地图的数据看板
  4. 原码、反码、补码的相互转换
  5. php div 居中代码,用CSS实现DIV水平居中显示
  6. 国际标准码 计算机,蒙古文国际标准编码到形码转换方法、装置及计算机终端与流程...
  7. 关于计算机的英语演讲话题,大学生英语演讲话题
  8. 彩虹代shua最新6.6版本源码/修改版/后台同步官方版本升级
  9. VoLTE / VoIP 网络电话
  10. 2019 Selenium3与Python3实战开发Web自动化测试框架(三)