noTS LTV转PDF文件。错误签名已定义。必须在PdfSignatureAppearance中关闭

时间:2017-08-02 15:31:36

标签: pdf itext

我想签名并添加LTV但尚未签名的PDF。

我已经从iText示例和qustions中复制了编码 http://developers.itextpdf.com/question/how-enable-ltv-timestamp-signature

主要方法的基本部分:

     Security.addProvider(new BouncyCastleProvider());
     EncryptPDF pdf = new EncryptPDF();

     OCSPVerifier ocspVerifier = new OCSPVerifier(null, null);
     OcspClient ocsp = new OcspClientBouncyCastle(ocspVerifier);

     pdf.signPDF(file_src, file_temp, ocsp);
     pdf.addLtvNoTS(file_temp, file_dest, ocsp);

方法signPDF签名没有问题(或现在注释加密)。临时文件没问题。

private void signPDF(String src, String dest, OcspClient ocsp) {
  try {
     PdfReader reader = new PdfReader(src);

     KeyStore ks = KeyStore.getInstance("pkcs12", "BC");
     ks.load(new FileInputStream(cert2_src), keystore_password.toCharArray());
     String alias = null;
     Enumeration<String> en = ks.aliases();
     while(en.hasMoreElements()) {
        alias = en.nextElement();
        System.out.println("alias name: " + alias);
     }

     PrivateKey pk = (PrivateKey) ks.getKey(alias, key_password.toCharArray());
     Certificate[] chain = ks.getCertificateChain(alias);

     PdfStamper stamper = PdfStamper.createSignature(reader, new FileOutputStream(dest), '\0', null, true);

     // appearance
     PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
     appearance.setImage(Image.getInstance(res_src));
     appearance.setVisibleSignature(new Rectangle(172, 132, 572, 232), 1, "SignatureField");   

     //         Certificate cert = getPublicCertificate(cert_src);
     //         stamper.setEncryption(new Certificate[]{cert},
     //            new int[]{PdfWriter.ALLOW_PRINTING}, PdfWriter.ENCRYPTION_AES_128 );   //| PdfWriter.DO_NOT_ENCRYPT_METADATA


     // digital signature
     ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "BC");
     ExternalDigest digest = new BouncyCastleDigest();
     MakeSignature.signDetached(appearance, digest, es, chain, null, ocsp, null, 0, CryptoStandard.CMS);

  } catch (FileNotFoundException e){
     e.printStackTrace();
  } catch (Exception e) {
     e.printStackTrace();
  }
}

在方法addLtvNoTS中我收到错误&#34;签名已定义。必须在PdfSignatureAppearance中关闭。&#34;在最后一行stamper.close()。我无法解决这个问题。请帮忙。

private void addLtvNoTS(String src, String dest, OcspClient ocsp)
     throws IOException, DocumentException, GeneralSecurityException {
  PdfReader r = new PdfReader(src);
  FileOutputStream fos = new FileOutputStream(dest);
  PdfStamper stamper = PdfStamper.createSignature(r, fos, '\0', null, true);
  LtvVerification v = stamper.getLtvVerification();
  AcroFields fields = stamper.getAcroFields();
  ArrayList<String> names = fields.getSignatureNames();
  String sigName = names.get(names.size() - 1);

  PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
  v.addVerification(sigName, ocsp, null,
        LtvVerification.CertificateOption.WHOLE_CHAIN,
        LtvVerification.Level.OCSP,
        LtvVerification.CertificateInclusion.NO);
  stamper.close(); 
}

1 个答案:

答案 0 :(得分:2)

您的addLtvNoTS方法似乎首先是文章中addLtv方法的副本,然后您不完全编辑该方法,以成为addLtvNoTS方法的副本。

特别是您的addLtvNoTS方法仍然包含文章addLtv方法

中的这一行
PdfStamper stamper = PdfStamper.createSignature(r, fos, '\0', null, true);

在文章addLtvNoTS方法中,相应的行是:

PdfStamper stp = new PdfStamper(r, fos, '\0', true);

因此,您创建了一个PdfStamper用于签名或时间戳(因此iText最终会抱怨您不这样做),而您应该创建一个不是。