IText5實現PDF簽章流程

public class ReadMe  {

    public static void main(String[] args) throws Exception {


        //1、創建PDF閱讀器
        PdfReader pdfReader = new PdfReader("需要簽章的PDF文件路徑");

        //2、創建簽章工具PdfStamper
        //最後一個參數false的話:PDF文件只允許被簽名一次,多次簽名時最後一次有效;true的話:可以被追加簽名,驗籤工具可以識別出每次簽名之後文檔是否被修改
        PdfStamper pdfStamper = PdfStamper.createSignature(pdfReader, new FileOutputStream("簽章後的PDF文件路徑"),
                '\0', null, true);


        //3、創建數字簽名域
        int x = 300, y = 400, width = 200, height = 200;
        Rectangle areaSignatureRect = new Rectangle(x, y, x + width, y + height);  //簽名區域
        PdfFormField formField = PdfFormField.createSignature(pdfStamper.getWriter());
        formField.setFieldName("AREA_SIGNATURE");  //簽名域標識
        formField.setPage(1);  //PDF頁碼從1開始
        formField.setWidget(areaSignatureRect, PdfAnnotation.HIGHLIGHT_OUTLINE);  //高亮顯示
        //可以通過PdfAppearance對象對這塊區域外觀做下調整
        PdfAppearance pdfAppearance = PdfAppearance.createAppearance(pdfStamper.getWriter(), width, height); //設置區域的寬高和邊框厚度
        pdfAppearance.setColorStroke(BaseColor.LIGHT_GRAY);  //邊框顏色
        pdfAppearance.setColorFill(BaseColor.YELLOW);  //填充顏色
        //填充矩形區域-開始
        pdfAppearance.rectangle(0, 0, width, height);
        //填充矩形區域-結束
        pdfAppearance.fillStroke();
        //添加文字
        pdfAppearance.setColorFill(BaseColor.BLACK);  //填充顏色重置爲黑色,用於顯示文字
        ColumnText.showTextAligned(pdfAppearance, Element.ALIGN_CENTER, new Phrase("簽名區域",
                new Font(Font.FontFamily.SYMBOL, 9.0F, Font.NORMAL, new BaseColor(0.0F, 0.0F, 0.0F, 0.5F))),
                width / 2, height / 2, 0);
        //將外觀應用到簽名域對象上
        formField.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, pdfAppearance);
        //最後將簽名對象作爲標註添加到PdfStamper對象
        pdfStamper.addAnnotation(formField, 1);




        //3、獲取數字簽章屬性對象,設定數字簽章屬性(對簽名域的屬性進行調整)
        PdfSignatureAppearance appearance = pdfStamper.getSignatureAppearance();
        appearance.setReason("簽名原因,顯示在PDF簽名屬性中");
        appearance.setLocation("簽名地點,顯示在PDF簽名屬性中");
        //設置簽名的位置,頁碼、簽名域名稱,多次追加簽名的時候簽名域名稱不能一樣
        appearance.setVisibleSignature(new Rectangle(200, 200, 300, 300), 1, "sig1");
        //讀取印章圖片
        Image image = Image.getInstance("C:\\gongzhang.png");
        appearance.setSignatureGraphic(image);
        appearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
        //設置圖章的顯示方式,如下選擇的只是顯示圖章(還有其他模式,可以圖章和簽名描述一起顯示)
        appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);

        //這裏iText提供了兩個用於簽名的接口,可以自己實現
        ExternalDigest digest = new BouncyCastleDigest();  //摘要算法
        //讀取keystore,獲取私鑰和證書鏈
        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(new FileInputStream("C:\\pdf\\test.p12"), "111111".toCharArray());
        String alias = ks.aliases().nextElement();
        PrivateKey pk = (PrivateKey) ks.getKey(alias, "111111".toCharArray());  //簽名私鑰
        ExternalSignature signature = new PrivateKeySignature(pk, DigestAlgorithms.SHA1, null);  //簽名算法
        Certificate[] chain = ks.getCertificateChain(alias);  //證書鏈
        MakeSignature.CryptoStandard subFilter = MakeSignature.CryptoStandard.CMS;  //數字簽名格式,iText有兩種

        //調用iText簽名方法完成PDF簽章
        MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null,
                0, subFilter);

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章