50kb 的 PDF 文件大小在使用之前使用 Itext Java 应用程序签名后急剧增加到 9mb

PDF File size of 50kb increases dramatically up to 9mb after signing it with previously using Itext Java Application

我正在使用基于 java 的自定义构建 itext 应用程序对 pdf 文件进行数字签名。

过去一年一切正常,但最近输出签名 pdf 文件的大小急剧增加,仅 50kb 源 pdf 文件就增加到 10MB。

之前对于 50 kb 的文件,输出小于 300 kb。

请找到代码片段

public void sign(String src, String dest,
        Certificate[] chain, PrivateKey pk,
        String digestAlgorithm, String provider, MakeSignature.CryptoStandard subfilter,
        String reason, String location,
        Collection<CrlClient> crlList,
        OcspClient ocspClient,
        TSAClient tsaClient,
        int estimatedSize)
                throws GeneralSecurityException, IOException, DocumentException {
    // Creating the reader and the stamper
    PdfReader reader = new PdfReader(src);
    FileOutputStream os = new FileOutputStream(dest);
    PdfStamper stamper = PdfStamper.createSignature(reader, os, '[=11=]');
    // Creating the appearance
    PdfSignatureAppearance appearance = stamper.getSignatureAppearance();

    ExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider);
    ExternalDigest digest = new BouncyCastleDigest();
    MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
}

public PrivateKey getPrivateKey(String DLL,String PIN,String usage) throws GeneralSecurityException, IOException {
    LoggerFactory.getInstance().setLogger(new SysoLogger());

    String config = "name=eToken\n" + "library=" + DLL + "\n";
    ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes());
    Provider providerPKCS11 = new SunPKCS11(bais);
    Security.addProvider(providerPKCS11);
    //System.out.println(providerPKCS11.getName());
    BouncyCastleProvider providerBC = new BouncyCastleProvider();
    Security.addProvider(providerBC);
    PrivateKey pk = null;  
    KeyStore ks = KeyStore.getInstance("PKCS11");

    try{
        ks.load(null, PIN.toCharArray());
        String alias = (String)ks.aliases().nextElement();

        java.util.Enumeration<String> aliases = ks.aliases();

        while (aliases.hasMoreElements()) {
            alias = aliases.nextElement();
            //System.out.println(alias);
            X509Certificate c = (X509Certificate) ks.getCertificate(alias);
            final boolean[] keyUsage = c.getKeyUsage();
            if(usage=="0" &&(keyUsage[0] || keyUsage[1]))
            {
                //System.out.println("Digital Signature");
                pk = (PrivateKey)ks.getKey(alias, PIN.toCharArray());
                this.providerPKCS11 = providerPKCS11.getName();
                this.pub_key = c;
                this.chain = ks.getCertificateChain(alias);

                for (int i = 0; i < this.chain.length; i++) {
                    // System.out.println(chain[i]);
                    X509Certificate cert = (X509Certificate)chain[i];
                    String tsaUrl = CertificateUtil.getTSAURL(cert);
                    if (tsaUrl != null) {
                        tsaClient = new TSAClientBouncyCastle(tsaUrl);
                        break;
                    }
                }

                crlList.add(new CrlClientOnline(chain));
            }
            else if(usage=="2" &&keyUsage[2])
            {
                //System.out.println("Encryption");
                pk = (PrivateKey)ks.getKey(alias, PIN.toCharArray());
                this.pub_key = c;
            }

            //alias1=alias;
        }
    }
    catch(Exception e)
    {
        System.out.println("Key Store Not loaded .. PIN entered may be incorrect");
    }

    return pk;
}

主要功能是

token.sign("D:\15 SAMPLE PDF FILES\15 SAMPLE PDF FILES\"+listOfFiles[i].getName(), "D:\15 SAMPLE PDF FILES\15 SAMPLE PDF FILES\sign\singn_"+listOfFiles[i].getName(), token.chain, PK_sign, DigestAlgorithms.SHA256, token.providerPKCS11, MakeSignature.CryptoStandard.CMS,
                "Sign", "Kottayam", token.crlList, token.ocspClient, token.tsaClient, 0);

上周我们的防火墙发生了变化。是这个问题吗?

如果签署 PDF 的过程突然导致文件比以前大得多,原因通常与嵌入式验证相关信息有关,特别是嵌入式 CRL(证书撤销列表)可能非常大。

原因可能纯粹是在 PKI 内部。例如。如果在发现相关的签名生成设备不安全后突然吊销大量证书,那么以前很小的CRL可能会突然变得非常大。

这也可能是连接问题。例如

  • 如果 PKI 的 OCSP 响应者以前可以访问但突然不再访问,则签名过程可能会改用 CRL;或
  • 如果吊销信息之前根本无法访问并且突然可以访问,则签名过程也可能开始使用 CRL。

事实证明,正如 OP 报道的那样,这里的情况是后者:

It was because of the firewall change. Initially the server will not look for crl url and so it doesnt embedd crl since it is not connecting to internet because of the firewall authentication. Unfortunately the firewall change cleared all the authentication and hence the server got the internet access and crl embedds in the signature.

可以通过禁止使用 CRL 来防止此类情况发生。在本例中,sign 方法的 Collection<CrlClient> crlList 参数可以简单地留空。

基本上,如果您不想包含 CRL 或 OCSP 响应,请不要向签名过程提供请求它们的方法。