0

我正在尝试即时签署 PDF。我显然没有这样做。任何帮助表示赞赏。

这只是签署 pdf 的测试。为了以后的目的,我将保存那些私钥和公钥。

目的是动态生成签名 PDF。我按照此链接中显示的代码

以下是代码片段。


import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Date;

import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfSignatureAppearance;
import com.lowagie.text.pdf.PdfStamper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SignPdf {

    Logger logger = LoggerFactory.getLogger(SignPdf.class);

    private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME;

    public byte[] getSignature(byte[] originalBytes, Application oap) throws Exception {

        ByteArrayOutputStream os = new ByteArrayOutputStream();

        KeyPairGenerator generator = KeyPairGenerator.getInstance ("RSA");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        
        generator.initialize (1024, random);
        
        KeyPair keyPair = generator.generateKeyPair();

        X509Certificate[] chain = 
                                {
                                    this.getSelfCertificate(
                                            keyPair, 
                                            "", 
                                            "", 
                                            "", 
                                            oap.getDateOfApply(), 
                                            oap.getDateOfReturn(), 
                                            ""
                                    )
                                };
        // reader and stamper
        PdfReader reader = new PdfReader(originalBytes);

        PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');

        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setReason("REASON");
        appearance.setLocation("");
        appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
        appearance.setCrypto(keyPair.getPrivate(), chain, null, PdfSignatureAppearance.SELF_SIGNED);
        
        stamper.close();

        return os.toByteArray();
    }


    private X509Certificate getSelfCertificate(
        KeyPair keyPair, 
        String organisation, 
        String orgUnit, 
        String commonName, 
        Date issueDate,
        Date validToDate,
        String signatureAlgorithm
    ){
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

            X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE);
            builder.addRDN(BCStyle.OU, orgUnit);
            builder.addRDN(BCStyle.O, organisation);
            builder.addRDN(BCStyle.CN, commonName);

            BigInteger serial = BigInteger.valueOf(System.currentTimeMillis());

            X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(
                                                    builder.build(),
                                                    serial, 
                                                    issueDate, 
                                                    validToDate, 
                                                    builder.build(), 
                                                    keyPair.getPublic()
                                                );

            ContentSigner sigGen = new JcaContentSignerBuilder(signatureAlgorithm)
                                        .setProvider(BC)
                                        .build(keyPair.getPrivate());

            X509Certificate cert = new JcaX509CertificateConverter()
                                        .setProvider(BC)
                                        .getCertificate(
                                            certGen
                                            .build(sigGen)
                                        );
            cert.checkValidity(new Date());
            cert.verify(cert.getPublicKey());

            return cert;
        } catch (Exception e) {
            logger.error("{}", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

}

这段代码运行时我无法弄清楚错误。

java.lang.ClassCastException: org.bouncycastle.asn1.ASN1UTCTime incompatible with org.bouncycastle.asn1.ASN1Set
        at com.lowagie.text.pdf.PdfPKCS7$X509Name.<init>(PdfPKCS7.java:1724)
        at com.lowagie.text.pdf.PdfPKCS7.getSubjectFields(PdfPKCS7.java:1149)
        at com.lowagie.text.pdf.PdfSignatureAppearance.getAppearance(PdfSignatureAppearance.java:483)
        at com.lowagie.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:1045)
        at com.lowagie.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:963)
        at com.lowagie.text.pdf.PdfStamper.close(PdfStamper.java:219)
        at com.blah.SignPdf.getSignature(SignPdf.java:94) // this is  stamper.close();

Maven配置是

        <dependency>
            <groupId>com.github.librepdf</groupId>
            <artifactId>openpdf</artifactId>
            <version>1.2.21</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.66</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcmail-jdk15on</artifactId>
            <version>1.64</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bctsp-jdk15on</artifactId>
            <version>1.46</version>
        </dependency>
4

1 回答 1

1

感谢mkl

我能够通过更新 openpdf 版本来解决这个问题

更新的 Maven 配置是

        <dependency>
            <groupId>com.github.librepdf</groupId>
            <artifactId>openpdf</artifactId>
            <version>1.3.23</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.66</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcmail-jdk15on</artifactId>
            <version>1.64</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bctsp-jdk15on</artifactId>
            <version>1.46</version>
        </dependency>
于 2020-11-18T17:21:52.410 回答