• pdf文件签名的问题解决


    1 pdf转图片乱码问题
    pdf是正常的,但是由pdf转成的图片,只要是中文,却是一堆框框,像这个问题,应该就是centos缺少字符集导致的
    1
    执行命令fc-list :lang=zh,可以看到正常的如下:
    1
    而有问题的机器,则显示没有安装
    1
    依据上面的推论,执行

    # 文泉驿微米黑字体
    yum install -y wqy-microhei-fonts
    
    • 1
    • 2

    执行完成后可以看到
    2
    那么其他的字符集,仿照写一些命令,执行的结果就跟之前的一木一样了。这样问题就解决了。

    yum install -y fontconfig mkfontscale
    yum install -y wqy-microhei-fonts
    yum install -y wqy-zenhei-fonts
    yum install -y cjkuni-uming-fonts
    
    • 1
    • 2
    • 3
    • 4

    还有种办法,就是将windows中的字体都复制过来,将这个文件复制到自己定义的目录
    1
    有的环境,需要重新机器才能生效。

    mkdir -p /usr/share/fonts/win/Fonts
    chmod -R 755 /usr/share/fonts/win/Fonts
    yum install ttmkfdir -y
    ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir
    # 把你的目录配置进去
    vim /etc/fonts/fonts.conf
    # 刷新字体缓存
    fc-cache
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2

    2 今天解决冲突的jar,结果出现下面的问题

    java.lang.IllegalAccessError: tried to access method org.bouncycastle.asn1.DERNull.<init>()V from class com.itextpdf.text.pdf.security.PdfPKCS7
            at com.itextpdf.text.pdf.security.PdfPKCS7.getEncodedPKCS7(PdfPKCS7.java:836)
            at com.itextpdf.text.pdf.security.MakeSignature.signDetached(MakeSignature.java:154)
            at com.whty.einv.sks.model.util.SignatureUtil.sign(SignatureUtil.java:97)
            at com.whty.einv.sks.model.util.SignatureUtil.sign(SignatureUtil.java:157)
            at com.whty.einv.sks.model.util.SignatureUtil.sign(SignatureUtil.java:143)
            at com.whty.einv.sks.model.service.impl.LocalSignatureStrategy.sign(LocalSignatureStrategy.java:38)
            at com.whty.einv.sks.model.service.AbstractInvoicePdfService.genPdf(AbstractInvoicePdfService.java:135)
            at com.whty.einv.sks.model.service.AbstractInvoicePdfService.genPdf(AbstractInvoicePdfService.java:99)
            at com.whty.einv.sks.model.service.AbstractInvoicePdfService.asyncGenPdf(AbstractInvoicePdfService.java:77)
            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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
            at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(Thr
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    按照kotlin 使用Itext5签署PDF在Quarkus中出现错误“PdfPKCS7无法访问void org.bouncycastle.asn1.DERNull.< init>()”
    设置并不能解决问题。

     <dependency>
                <groupId>org.bouncycastlegroupId>
                <artifactId>bcprov-jdk15onartifactId>
                <version>1.70version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    按照PDF文件的数字签名编写,再本地可以运行,但是发布到容器环境中,提示下面的错误,主要原还是因为bcprov-jdk15on,因为jar冲突被排除了。

    java.lang.NoClassDefFoundError: org/bouncycastle/jcajce/provider/digest/MD2$Digest
            at com.whty.einv.sks.model.util.SignUtil.sign(SignUtil.java:111)
            at com.whty.einv.sks.model.util.SignUtil.sign(SignUtil.java:83)
            at com.whty.einv.sks.model.util.SignUtil.sign(SignUtil.java:69)
            at com.whty.einv.sks.model.service.impl.LocalSignatureStrategy.sign(LocalSignatureStrategy.java:38)
            at com.whty.einv.sks.model.service.AbstractInvoicePdfService.genPdf(AbstractInvoicePdfService.java:135)
            at com.whty.einv.sks.model.service.AbstractInvoicePdfService.genPdf(AbstractInvoicePdfService.java:99)
            at com.whty.einv.sks.model.service.AbstractInvoicePdfService.asyncGenPdf(AbstractInvoicePdfService.java:77)
            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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
            at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at java.lang.Thread.run(Thread.java:748)
    Caused by: java.lang.ClassNotFoundException: org.bouncycastle.jcajce.provider.digest.MD2$Digest
            at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
            at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:135)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
            ... 19 common frames omitted
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    现在对比一下新模式,这里的reason是必填,否则会报错,与旧模式有区别

    package com.whty.einv.sks.model.util;
    
    import com.itextpdf.io.image.ImageData;
    import com.itextpdf.io.image.ImageDataFactory;
    import com.itextpdf.kernel.geom.Rectangle;
    import com.itextpdf.kernel.pdf.PdfReader;
    import com.itextpdf.kernel.pdf.StampingProperties;
    import com.itextpdf.signatures.*;
    import com.itextpdf.signatures.PdfSignatureAppearance.RenderingMode;
    import com.whty.framework.base.util.CheckEmptyUtil;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.security.GeneralSecurityException;
    import java.security.KeyStore;
    import java.security.PrivateKey;
    import java.security.cert.Certificate;
    
    /**
     * @author dj
     * @create 2023-09-05 19:00
     */
    public class SignUtil {
    
        public static void sign(String src, String dest, String img, KeyStore keyStore, String password, String digestAlgorithm,
                                PdfSigner.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), img, chain, PrivateKey, digestAlgorithm, sigtype, reason, location);
        }
    
        public static void sign(String src, String dest, String img, KeyStore keyStore, String password, String digestAlgorithm,
                                PdfSigner.CryptoStandard sigtype) throws GeneralSecurityException, IOException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), img, chain, PrivateKey, digestAlgorithm, sigtype, null, null);
        }
    
        public static void sign(String src, String dest, KeyStore keyStore, String password, String digestAlgorithm,
                                PdfSigner.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), null, chain, PrivateKey, digestAlgorithm, sigtype, reason, location);
        }
    
        public static void sign(String src, String dest, KeyStore keyStore, String password, String digestAlgorithm,
                                PdfSigner.CryptoStandard sigtype) throws GeneralSecurityException, IOException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), null, chain, PrivateKey, digestAlgorithm, sigtype, null, null);
        }
    
        public static void sign(String src, String dest, String img, KeyStore keyStore, String password,String reason, String location) throws GeneralSecurityException, IOException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), img, chain, PrivateKey, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CMS, reason, location);
        }
    
        public static void sign(String src, OutputStream outputStream, KeyStore keyStore, String password) throws GeneralSecurityException, IOException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, outputStream, null, chain, PrivateKey, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CMS, "岁月云", "");
        }
    
        public static void sign(String src, OutputStream outputStream, String img, KeyStore keyStore, String password) throws GeneralSecurityException, IOException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, outputStream, img, chain, PrivateKey, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CMS, null, null);
        }
    
        public static void sign(String src, OutputStream outputStream, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm,
                                PdfSigner.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException {
    
            PdfReader pdfReader = new PdfReader(src);
            sign(pdfReader,outputStream,img,chain,pk,digestAlgorithm,sigtype,reason,location);
        }
    
    
        public static void sign(PdfReader pdfReader, OutputStream outputStream, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm,
                                PdfSigner.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException {
            PdfSigner signer = new PdfSigner(pdfReader,outputStream,new StampingProperties());
            // 获取数字签章属性对象,设定数字签章的属性
            PdfSignatureAppearance appearance = signer.getSignatureAppearance();
            appearance.setReason(reason);
            appearance.setLocation(location);
            /**
             * 1 三个参数依次为:设置签名的位置、页码、签名域名称,多次追加签名的时候,签名域名称不能一样
             *  1.1 签名的位置四个参数:印章左下角的X、Y轴坐标,印章右上角的X、Y轴坐标,
             * 		这个位置是相对于PDF页面的位置坐标,即该坐标距PDF当前页左下角的坐标
             */
            Rectangle rect = new Rectangle(460, 0, 590, 90);
            appearance.setReuseAppearance(false).setPageRect(rect).setPageNumber(1);
            if(CheckEmptyUtil.isEmpty(img)) {
                img = SignUtil.class.getClassLoader().getResource("seal/empty.png").getPath();
            }
            ImageData imageData = ImageDataFactory.create(img);
            appearance.setSignatureGraphic(imageData);
            appearance.setRenderingMode(RenderingMode.GRAPHIC);
            /**
             * 算法主要为:RSA、DSA、ECDSA
             * 摘要算法,这里的itext提供了2个用于签名的接口,可以自己实现
             */
            IExternalDigest digest = new BouncyCastleDigest();
            /**
             * 签名算法,参数依次为:证书秘钥、摘要算法名称,例如MD5 | SHA-1 | SHA-2.... 以及 提供者
             */
            IExternalSignature   signature = new PrivateKeySignature(pk, digestAlgorithm, null);
            signer.signDetached(digest, signature, chain, null, null, null, 0, sigtype);
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120

    旧模式,用法差不多,但是jar包的使用差异很大

    package com.whty.einv.invoice.util;
    
    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.Image;
    import com.itextpdf.text.Rectangle;
    import com.itextpdf.text.pdf.PdfContentByte;
    import com.itextpdf.text.pdf.PdfReader;
    import com.itextpdf.text.pdf.PdfSignatureAppearance;
    import com.itextpdf.text.pdf.PdfStamper;
    import com.itextpdf.text.pdf.security.*;
    import com.whty.framework.base.util.CheckEmptyUtil;
    import org.apache.commons.io.FileUtils;
    
    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.security.GeneralSecurityException;
    import java.security.KeyStore;
    import java.security.PrivateKey;
    import java.security.cert.Certificate;
    
    
    /**
     * 签名工具类
     */
    public class SignatureUtil {
    
    
        /**
         * 签名
         * @param pdfReader 需要签章的pdf
         * @param dest 签完章的pdf文件路径
         * @param chain 证书链
         * @param img 印章图片
         * @param pk 签名私钥
         * @param digestAlgorithm 摘要算法名称,例如SHA-1
         * @param sigtype 数字签名格式,itext有2种
         * @param reason 签名的原因,显示在pdf签名属性中
         * @param location 签名的地点,显示在pdf签名属性中
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        public static void sign(PdfReader pdfReader, OutputStream outputStream, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm,
                                MakeSignature.CryptoStandard sigtype, String reason, String location,InputStream sealInputStream,int[] imageLocation) throws GeneralSecurityException, IOException, DocumentException {
    
            /**
             * 1 参数依次为:文件名、文件输入流、文件版本号、临时文件、是否可以追加签名
             *  1.1 false的话,pdf文件只允许被签名一次,多次签名,最后一次有效
             *  1.2 true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改
             */
            // Create a PDF stamper
            PdfStamper stamper = PdfStamper.createSignature(pdfReader, outputStream, '\0', null, false);
            if(imageLocation == null){
                imageLocation = new int[]{460, 0, 130, 90};
            }
            if(sealInputStream != null){
                // Load the image
                BufferedImage image = ImageIO.read(sealInputStream);
                // Create a PDF image
                Image pdfImage = Image.getInstance(image, null);
                // Get the content of the first page
                PdfContentByte content = stamper.getOverContent(1);
                // Add the image to the specified location and with the specified dimensions
                pdfImage.setAbsolutePosition(imageLocation[0], imageLocation[1]);
                pdfImage.scaleAbsolute(imageLocation[2], imageLocation[3]);
                content.addImage(pdfImage);
            }
    
    
            // 获取数字签章属性对象,设定数字签章的属性
            PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
            appearance.setReason(reason);
            appearance.setLocation(location);
            /**
             * 1 三个参数依次为:设置签名的位置、页码、签名域名称,多次追加签名的时候,签名域名称不能一样
             *  1.1 签名的位置四个参数:印章左下角的X、Y轴坐标,印章右上角的X、Y轴坐标,
             * 		这个位置是相对于PDF页面的位置坐标,即该坐标距PDF当前页左下角的坐标
             */
            appearance.setVisibleSignature(new Rectangle(imageLocation[0], imageLocation[1], imageLocation[0]+imageLocation[2], imageLocation[1]+imageLocation[3]), 1, "sign");
    
            /**
             * 用于盖章的印章图片,引包的时候要引入itext包的image
             */
            if(CheckEmptyUtil.isEmpty(img)) {
                img = SignatureUtil.class.getClassLoader().getResource("seal/empty.png").getPath();
            }
            appearance.setSignatureGraphic(Image.getInstance(img));
    
            /**
             * 设置认证等级,共4种,分别为:
             *  NOT_CERTIFIED、CERTIFIED_NO_CHANGES_ALLOWED、
             *  CERTIFIED_FORM_FILLING 和 CERTIFIED_FORM_FILLING_AND_ANNOTATIONS
             *
             * 需要用哪一种根据业务流程自行选择
             */
            appearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
    
            /**
             * 印章的渲染方式,同样有4种:
             *  DESCRIPTION、NAME_AND_DESCRIPTION,
             *  GRAPHIC_AND_DESCRIPTION,GRAPHIC;
             * 这里选择只显示印章
             */
            appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
    
            /**
             * 算法主要为:RSA、DSA、ECDSA
             * 摘要算法,这里的itext提供了2个用于签名的接口,可以自己实现
             */
            ExternalDigest digest = new BouncyCastleDigest();
            /**
             * 签名算法,参数依次为:证书秘钥、摘要算法名称,例如MD5 | SHA-1 | SHA-2.... 以及 提供者
             */
            ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, null);
            /**
             * 最重要的来了,调用itext签名方法完成pdf签章
             */
            MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, sigtype);
        }
    
        public static void sign(String src, String dest, String img, KeyStore keyStore, String password, String digestAlgorithm,
                                MakeSignature.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException, DocumentException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), img, chain, PrivateKey, digestAlgorithm, sigtype, reason, location);
        }
    
        public static void sign(String src, String dest, String img, KeyStore keyStore, String password, String digestAlgorithm,
                                MakeSignature.CryptoStandard sigtype) throws GeneralSecurityException, IOException, DocumentException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), img, chain, PrivateKey, digestAlgorithm, sigtype, null, null);
        }
    
        public static void sign(String src, String dest, KeyStore keyStore, String password, String digestAlgorithm,
                                MakeSignature.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException, DocumentException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), null, chain, PrivateKey, digestAlgorithm, sigtype, reason, location);
        }
    
        public static void sign(String src, String dest, KeyStore keyStore, String password, String digestAlgorithm,
                                MakeSignature.CryptoStandard sigtype) throws GeneralSecurityException, IOException, DocumentException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), null, chain, PrivateKey, digestAlgorithm, sigtype, null, null);
        }
    
        public static void sign(String src, String dest, KeyStore keyStore, String password) throws GeneralSecurityException, IOException, DocumentException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, new FileOutputStream(dest), null, chain, PrivateKey, DigestAlgorithms.SHA1, MakeSignature.CryptoStandard.CMS, null, null);
        }
    
        public static void sign(String src, OutputStream outputStream, KeyStore keyStore, String password) throws GeneralSecurityException, IOException, DocumentException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, outputStream, null, chain, PrivateKey, DigestAlgorithms.SHA1, MakeSignature.CryptoStandard.CMS, null, null);
        }
    
        public static void sign(String src, OutputStream outputStream, String img, KeyStore keyStore, String password) throws GeneralSecurityException, IOException, DocumentException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            sign(src, outputStream, img, chain, PrivateKey, DigestAlgorithms.SHA1, MakeSignature.CryptoStandard.CMS, null, null);
        }
    
        public static void sign(String src, OutputStream outputStream, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm,
                                MakeSignature.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException, DocumentException {
    
            PdfReader pdfReader = new PdfReader(src);
            sign(pdfReader,outputStream,img,chain,pk,digestAlgorithm,sigtype,reason,location,null,null);
        }
    
        public static void sign(byte[] originalPdf, OutputStream outputStream, KeyStore keyStore, String password,InputStream sealInputStream,int[] imgLocation) throws GeneralSecurityException, IOException, DocumentException {
            String alias = keyStore.aliases().nextElement();
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            Certificate[] chain = keyStore.getCertificateChain(alias);
            PdfReader pdfReader = new PdfReader(originalPdf);
            sign(pdfReader, outputStream, null, chain, privateKey, DigestAlgorithms.SHA1, MakeSignature.CryptoStandard.CMS, null, null,sealInputStream,imgLocation);
        }
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
  • 相关阅读:
    普通人如何获得通信达接口?
    【英语语法】so
    期货开户手续费是怎么查询?
    Hadoop完全分布式的搭建
    ASEMI肖特基二极管SBT40100VFCT规格,SBT40100VFCT封装
    永远无法实现的“诚实“
    java基于微信小程序的在线药品购买销售商城系统 uinapp 计算机毕业设计
    结构赋值是浅拷贝还是深拷贝
    mybatisplus快速实现动态数据源切换
    MySQL中的隐式转换造成的索引失效
  • 原文地址:https://blog.csdn.net/warrah/article/details/132698185