PDF使用Itext Java Application进行签名后,50kb的文件大小会急剧增加到9mb

时间:2018-02-21 11:22:46

标签: certificate itext digital-signature

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

在过去的一年中,每件事情都运行良好,但最近输出的签名pdf文件的大小大幅增加到10 MB,仅用于50kb的源pdf文件。

早期的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, '\0');
    // 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);

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

1 个答案:

答案 0 :(得分:1)

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

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

这也可能是连通性的问题。例如

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

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

  

这是因为防火墙的变化。最初服务器不会查找crl url,因此它不会嵌入crl,因为它没有连接到Internet,因为防火墙身份验证。不幸的是,防火墙更改清除了所有身份验证,因此服务器获得了Internet访问权限并且crl嵌入了签名中。

通过禁止使用CRL可以防止这样的事情发生。在目前的情况下,Collection<CrlClient> crlList方法的sign参数可以简单地保留为空。

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