微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ExternalSignature itext问题

如何解决ExternalSignature itext问题

我正在开发一个程序,使用我在一些教程中找到的IExternalSignature接口使用PKCS11对PDF文档进行签名,这是除了实现的接口之外的主要代码

import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.StampingProperties;
import com.itextpdf.signatures.BouncyCastleDigest;
import com.itextpdf.signatures.IExternalDigest;
import com.itextpdf.signatures.IExternalSignature;
import com.itextpdf.signatures.PdfSignatureAppearance;
import com.itextpdf.signatures.PdfSigner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;

public class Sign {
    public static void signRemote(String certificate,String password,String token,String module,Long slot,String reason,String location,String contact,String input,String output
    ) throws CertificateException,FileNotFoundException,IOException,KeyStoreException,GeneralSecurityException {
        CertificateFactory factory = CertificateFactory.getInstance("X.509");
        Certificate[] chain = new Certificate[3];
        int i = 0;

        for(Certificate cert : factory.generateCertificates(
            new FileInputStream(certificate))
        ) {
            chain[i] = cert;
            i++;
        }

        PdfReader reader;
        
        reader = new PdfReader(input);
        PdfSigner signer = new PdfSigner(
            reader,new FileOutputStream(output),new StampingProperties()
        );
        signer.setCertificationLevel(PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED);

        PdfSignatureAppearance sap = signer.getSignatureAppearance();
        sap
            .setReason(reason)
            .setLocation(location)
            .setContact(contact);
        signer.setFieldName("signature");

        IExternalDigest digest = new BouncyCastleDigest();
        IExternalSignature signature = new PKCS11Signature(
            password,token,module,slot
        );

        signer.signDetached(
            digest,signature,chain,null,PdfSigner.CryptoStandard.CMS
        );

        reader.close();        
    }
import com.itextpdf.signatures.DigestAlgorithms;
import com.itextpdf.signatures.IExternalSignature;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.security.pkcs11.SunPKCS11;

public class PKCS11Signature implements IExternalSignature {
    private final String password;
    private final String token;
    private final String module;
    private final Long slot;

    public PKCS11Signature(
        String password,Long slot
    ) {
        this.password = password;
        this.token = token;
        this.module = module;
        this.slot = slot;
    }

    @Override
    public String getHashAlgorithm() {
        return DigestAlgorithms.SHA256;
    }

    @Override
    public String getEncryptionAlgorithm() {
        return "RSA";
    }

    @Override
    public byte[] sign(byte[] message) throws GeneralSecurityException {
        try {
            BouncyCastleProvider providerBC = new BouncyCastleProvider();
            Security.addProvider(providerBC);

            String config =
                "name = " + this.token + "\n" +
                "library = " + this.module + "\n" +
                "slot = " + this.slot;
            ByteArrayInputStream bais =
                new ByteArrayInputStream(config.getBytes());
            SunPKCS11 providerPKCS11 = new SunPKCS11(bais);
            Security.addProvider(providerPKCS11);

            // Load your private key from the key store
            KeyStore ks = KeyStore.getInstance("PKCS11",providerPKCS11);
            ks.load(null,this.password.tochararray());

            // load key or chain
            String alias = ks.aliases().nextElement();
            PrivateKey pk = (PrivateKey)ks.getKey(alias,null);

            // Sign the hash received from the server
            Signature sig = Signature.getInstance("SHA256withRSA");
            sig.initSign(pk);
            sig.update(message);

            return sig.sign();
        } catch (IOException |
            NoSuchAlgorithmException |
            CertificateException ex
        ) {
            Logger.getLogger(Signature.class.getName()
            ).log(Level.SEVERE,ex);
        }

        return null;
    }
}

我的异常如下:

com.itextpdf.kernel.PdfException: UnkNown PdfException.
    at com.itextpdf.signatures.PdfPKCS7.getEncodedPKCS7(PdfPKCS7.java:934)
    at com.itextpdf.signatures.PdfSigner.signDetached(PdfSigner.java:648)
    at com.itextpdf.signatures.PdfSigner.signDetached(PdfSigner.java:538)
    at pdf.pkcs11.Sign.signRemote(Sign.java:60)
    at pdf.pkcs11.SignTest.testSignRemote(SignTest.java:90)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:172)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:104)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:70)
Caused by: java.lang.NullPointerException
    at com.itextpdf.signatures.PdfPKCS7.getEncodedPKCS7(PdfPKCS7.java:857)
    ... 33 more

我在PDF规范方面经验不足,因此欢迎任何指导以纠正我的程序。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。