java操作pdf制作电子签章

#java操作pdf制作电子签章
##电子签章简介
电子签章,与我们所使用的数字证书一样,是用来做为身份验证的一种手段,泛指所有以电子形式存在,依附在电子文件并与其逻辑关联,可用以辨识电子文件签署者身份,保证文件的完整性,并表示签署者同意电子文件所陈述事实的内容。一般来说,对电子签章的认定,都是从技术角度而言的。主要是指通过特定的技术方案来鉴别当事人的身份及确保交易资料内容不被篡改的安全保障措施。从广义上讲,电子签章不仅包括我们通常意义上讲的"非对称性密钥加密",也包括计算机口令、生物笔迹辨别、指纹识别,以及新近出现的眼虹膜透视辨别法、面纹识别等。而电子签章技术作为目前最成熟的"数字签章",是以公钥及密钥的"非对称型"密码技术制作的。电子签章是电子签名的一种表现形式,利用图像处理技术将电子签名操作转化为与纸质文件盖章操作相同的可视效果,同时利用电子签名技术保障电子信息的真实性和完整性以及签名人的不可否认性 。
如果对数字证书,签名验签,摘要,数据签名不太理解的同学,可以参考我之前的文章
安全之加密算法(-)
openssl 自建ca,颁发客户端证书
具体了解下
##java代码实现
java 操作pdf的开源类库我大概了解了两种pdfbox,itextpdf,两个库各有优势,目前据我使用可知,pdfbox功能较为强大,但是定制性较小,itextpdf 可定制性较高
准备
p12 证书
测试电子签章图片

这里写图片描述
测试pdf

这里写图片描述

使用jar包
这里写图片描述
###itextpdf实现电子签章
itextpdf 提供了 MakeSignature 这个入口类,操作相对较为简单

封装下即可

public static void sign(InputStream src  //需要签章的pdf文件路径
            , OutputStream dest  // 签完章的pdf文件路径
            , InputStream p12Stream, //p12 路径
            char[] password
            , String reason  //签名的原因,显示在pdf签名属性中,随便填
            , String location,String chapterPath) //签名的地点,显示在pdf签名属性中,随便填
                    throws GeneralSecurityException, IOException, DocumentException {
		 //读取keystore ,获得私钥和证书链
        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(p12Stream, password);
        String alias = (String)ks.aliases().nextElement();
        PrivateKey pk = (PrivateKey) ks.getKey(alias, password);
        Certificate[] chain = ks.getCertificateChain(alias);
        
        //下边的步骤都是固定的,照着写就行了,没啥要解释的
        // Creating the reader and the stamper,开始pdfreader
        PdfReader reader = new PdfReader(src);
        //目标文件输出流
        //创建签章工具PdfStamper ,最后一个boolean参数 
        //false的话,pdf文件只允许被签名一次,多次签名,最后一次有效
        //true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改
        PdfStamper stamper = PdfStamper.createSignature(reader, dest, '\0', null, false);
        // 获取数字签章属性对象,设定数字签章的属性
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setReason(reason);
        appearance.setLocation(location);
        //设置签名的位置,页码,签名域名称,多次追加签名的时候,签名预名称不能一样
        //签名的位置,是图章相对于pdf页面的位置坐标,原点为pdf页面左下角
        //四个参数的分别是,图章左下角x,图章左下角y,图章右上角x,图章右上角y
        appearance.setVisibleSignature(new Rectangle(0, 800, 100, 700), 1, "sig1");
        //读取图章图片,这个image是itext包的image
        Image image = Image.getInstance(chapterPath);
        appearance.setSignatureGraphic(image); 
        appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
        //设置图章的显示方式,如下选择的是只显示图章(还有其他的模式,可以图章和签名描述一同显示)
        appearance.setRenderingMode(RenderingMode.GRAPHIC);

        // 这里的itext提供了2个用于签名的接口,可以自己实现,后边着重说这个实现
        // 摘要算法
        ExternalDigest digest = new BouncyCastleDigest();
        // 签名算法
        ExternalSignature signature = new PrivateKeySignature(pk, DigestAlgorithms.SHA1, null);
        // 调用itext签名方法完成pdf签章CryptoStandard.CMS 签名方式,建议采用这种
        MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, CryptoStandard.CMS);
	}

###pdfbox 实现电子签章
pdfbox 实现签名可以从pdfbox 官网示例中找到
svn地址
https://svn.apache.org/repos/asf/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/
简单封装示例

  public static void sign(char[] password,InputStream p12Input,FileInputStream imageStream,File srcPdf,File signed,String signerName,String reason,String location) throws Exception{
    	boolean externalSig=false;
    	KeyStore keystore = KeyStore.getInstance("PKCS12");
        keystore.load(p12Input, password);
        PdfSignBox signing = new PdfSignBox(keystore, password);
        File signedDocumentFile;
        int page=1;
		signing.setVisibleSignDesigner(srcPdf.toString(), 50, 100, -90, imageStream, page);
        signing.setVisibleSignatureProperties(signerName, location, reason, 0, page, true);
        signing.setExternalSigning(externalSig);
        signing.signPDF(srcPdf, signed, null);
    }

签名测试代码

package com.taoyuan.pdf.sign.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import com.taoyuan.pdf.sign.itext.PdfSignBox;
import com.taoyuan.pdf.sign.itext.PdfSignItext;

public class Test {
	public static void main(String[] args) throws  Exception {
		     String KEYSTORE="d://test.p12";
		       char[] PASSWORD = "123".toCharArray();//keystory密码
		       String SRC="d://demo.pdf" ;//原始pdf
		       String DEST="d://demo_signed_box.pdf" ;//签名完成的pdf
		       String DEST2="d://demo_signed_itext.pdf" ;//签名完成的pdf
		      String chapterPath="d://chapter.png";//签章图片
		      String signername="測試";
		      String reason="数据不可更改";
		      String location="桃源乡";
		     
	PdfSignBox.sign(PASSWORD, new FileInputStream(KEYSTORE), 
			new FileInputStream(chapterPath), 
			new File(SRC),new File(DEST),signername, reason, location);	
	
	
	PdfSignItext.sign(new FileInputStream(SRC), new FileOutputStream(DEST2), 
			new FileInputStream(KEYSTORE), PASSWORD, 
		 reason, location, chapterPath);
	}
}

签章效果,使用adboe reader打开pdf,查看
这里写图片描述

这里写图片描述

当然自己生成的证书去给pdf签章,是不被认可的,这种证书需要花钱的,大概1000多元一年吧

完整代码下载地址
http://download.csdn.net/download/do_bset_yourself/10010394

填坑之 根据关键词签章

  • 12
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
Java中,可以使用一些开源库来实现对PDF文件添加电子印章的功能。其中,常用的开源库包括iText和PDFBox。 一种常见的实现方式是使用iText库。首先,需要使用iText加载要进行操作PDF文件。然后,通过创建一个PdfReader对象,读取PDF文件的内容。接下来,可以使用PdfStamper类来创建一个新的PDF文件,并在新文件中添加电子印章。可以通过调用PdfStamper的addAnnotation()方法,在指定的位置添加一个电子印章。 在添加电子印章时,需要创建一个PdfSignatureAppearance对象,并设置印章的相关属性,例如印章的位置、大小、图片等。可以通过调用PdfSignatureAppearance的setSignatureGraphic()方法来设置印章的图片。此外,还需要创建一个数字证书,并通过调用PdfSignatureAppearance的setCrypto()方法来设置数字证书的相关信息。 完成设置后,需要调用PdfStamper的close()方法来保存并关闭新的PDF文件。现在,新的PDF文件中就成功添加了电子印章。 除了iText,另一个常用的库是PDFBox。使用PDFBox实现类似的功能也是可以的。使用PDFBox可以加载PDF文件,并使用AcroForms类来进行表单操作。可以通过AcroForms类的addSignatureField()方法来添加电子印章的表单域,并设置相应的属性。然后,通过创建一个PDDocument对象来保存并关闭新的PDF文件。 总结起来,使用Java语言,可以通过一些开源库(如iText和PDFBox)来实现对PDF文件进行电子印章的添加。具体的实现步骤是,加载PDF文件,创建一个新的PDF文件,设置电子印章的相关属性,并将电子印章添加到新的PDF文件中。最后,保存并关闭并且新的PDF文件就成功添加了电子印章。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值