java iText5 5.5.X版本 对pdf进行数字签名 在签名过程中应用时间戳

因为公司对发出的pdf报告进行有权威的认证,所以需要使用数字签名。

Apache PDFBox: 实现不了,
spire.pdf.free: 虽然可以用,但是免费的他有限制,限制了转为数字签名的pdf只有10页

iText5:所以使用了iText5

首先你要有CA证书、密码、以及时间戳服务器(TSA)的url、用户、密码。

接下来引入对应的jar

<!-- iText core library -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13.4</version>
        </dependency>

        <!-- Bouncy Castle Core Library -->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.70</version>
        </dependency>

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.70</version>
        </dependency>

然后就是代码了

package com.stc;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.security.BouncyCastleDigest;
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 com.itextpdf.text.pdf.security.TSAClientBouncyCastle;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.util.Enumeration;

/**
 * @ClassName: SignPdfWithTimestamp
 * @Description: TODO
 * @Author: ZhangZeYu
 * @date: 2024/7/3 14:39
 * @Version: V1.0
 */
public class SignPdfWithTimestamp {

    public static void main(String[] args) throws IOException, GeneralSecurityException, DocumentException {
        // 添加BouncyCastleProvider
        Security.insertProviderAt(new BouncyCastleProvider(), 1);

        // PDF文件路径
        String src = "E:/pdfszzs.pdf";
        // 签名后PDF文件路径
        String dest = "E:/pdfszzs22.pdf";
        // PKCS#12文件路径
        String pkcs12 = "E:/1111.pfx";
        // PKCS#12文件密码
        String password = "1111";
        // TSA服务器URL
        String tsaUrl = "http://your-tsa-server.com/ts";

        // 加载证书和私钥
        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(new java.io.FileInputStream(pkcs12), password.toCharArray());
        Enumeration<String> aliases = ks.aliases();
        String alias = aliases.nextElement();
        PrivateKey pk = (PrivateKey) ks.getKey(alias, password.toCharArray());
        Certificate[] chain = ks.getCertificateChain(alias);

        // 创建PDF阅读器和签署者
        PdfReader reader = new PdfReader(src);
        FileOutputStream os = new FileOutputStream(dest);
        PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setReason("Signed by example");
        appearance.setLocation("Somewhere");

        // 设置签名外观的其他属性,如签名位置等

        // 创建签名和摘要实例
        ExternalSignature pks = new PrivateKeySignature(pk, "SHA-256", "BC");
        ExternalDigest digest = new BouncyCastleDigest();

        // 创建时间戳客户端
        TSAClientBouncyCastle tsaClient = new TSAClientBouncyCastle(tsaUrl);

        // 执行签名并应用时间戳
        MakeSignature.signDetached(appearance, digest, pks, chain, null, null, tsaClient, 0, MakeSignature.CryptoStandard.CMS);

        // 关闭资源
        stamper.close();
        os.close();
    }
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值