我是iText 7的新手,我尝试通过使用addLtv()方法(下面提供的代码)将ltv信息添加到现有签名中,这个方法将crl或ocsp参数添加到现有签名或时间戳中,然后在文档上加盖时间戳,但是生成的pdf文档没有启用ltv。但是,如果我首先用ocsp或crl列表签署文档,我就能够生成ltv启用签名,这使我相信此问题与某些证书丢失或添加不当无关。因此,由于某种原因,addLtv()方法对我不起作用。我希望我说得有道理:D任何帮助或建议都很有用:)
private void addLtv(String src, String dest, IOcspClient ocsp, ICrlClient crl, ITSAClient tsa) throws Exception {
PdfReader r = new PdfReader(src);
FileOutputStream fos = new FileOutputStream(dest);
PdfDocument pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
PdfSigner ps= new PdfSigner(r, fos, true);
LtvVerification v = new LtvVerification(pdfDoc);
SignatureUtil signatureUtil = new SignatureUtil(pdfDoc);
List<String> names = signatureUtil.getSignatureNames();
String sigName = names.get(names.size() - 1);
PdfPKCS7 pkcs7 = signatureUtil.verifySignature(sigName);
if (pkcs7.isTsp()) {
v.addVerification(sigName, ocsp, crl,
LtvVerification.CertificateOption.WHOLE_CHAIN,
LtvVerification.Level.CRL,
LtvVerification.CertificateInclusion.YES);
}
else {
for (String name : names) {
v.addVerification(name, ocsp, crl,
LtvVerification.CertificateOption.WHOLE_CHAIN,
LtvVerification.Level.OCSP,
LtvVerification.CertificateInclusion.YES);
v.merge();
}
}
ps.timestamp(tsa, null);
}发布于 2017-03-24 11:23:12
代码中的概念问题是,在添加LTV信息之后,您希望通过时间戳来完成该过程。虽然这是您希望对已经在LTV工作流中的PDF所做的事情,但这并不是您希望Adobe将其声明为“支持LTV”的PDF的全部签名。
(人们可以认为Adobe的术语“LTV启用”意味着“准备好进入LTV工作流”,即还没有真正在LTV工作流中,而是包含了输入它所需的所有验证信息,而无需任何进一步的限制。)
在您的方法中还存在其他问题,例如,您创建了两个单独的对象,它们分别写入dest、PdfSigner ps通过fos和PdfDocument pdfDoc通过其PdfWriter。最终,您将在文件中找到其中一个对象的输出,或者找到这两个对象的mish-mash。
因此,下面是我的旧iText 5方法addLtvNoTS (从这个答案)到iText 7的工作端口:
void addLtvNoTS(InputStream src, OutputStream dest, IOcspClient ocsp, ICrlClient crl, LtvVerification.Level timestampLevel, LtvVerification.Level signatureLevel) throws IOException, GeneralSecurityException
{
PdfDocument pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(dest), new StampingProperties().useAppendMode());
LtvVerification v = new LtvVerification(pdfDoc);
SignatureUtil signatureUtil = new SignatureUtil(pdfDoc);
List<String> names = signatureUtil.getSignatureNames();
String sigName = names.get(names.size() - 1);
PdfPKCS7 pkcs7 = signatureUtil.verifySignature(sigName);
if (pkcs7.isTsp())
{
v.addVerification(sigName, ocsp, crl, LtvVerification.CertificateOption.WHOLE_CHAIN,
timestampLevel, LtvVerification.CertificateInclusion.YES);
}
else
{
for (String name : names)
{
v.addVerification(name, ocsp, crl, LtvVerification.CertificateOption.WHOLE_CHAIN,
signatureLevel, LtvVerification.CertificateInclusion.YES);
}
}
v.merge();
pdfDoc.close();
}(https://github.com/mkl-public/testarea-itext7/blob/master/src/test/java/mkl/testarea/itext7/signature/EnableLtv.java#L86 addLtvNoTS__)
如您所见,我为时间戳和签名方法参数创建了LtvVerification.Level值。
这是因为iText的方法LtvVerification.addVerification只为即时PDF签名和文档时间戳添加LTV信息,而不是已经嵌入或现在添加了OCSP响应或CRL签名。
这通常没有问题,通常用于签名OCSP响应的证书的标记方式表明不需要撤销检查,用于签名CRLs的证书通常是隐式信任的CA证书本身。
不过,对于我的测试签名,OCSP响应是由确实需要撤销检查的签名签名的。为了在不增加大量代码的情况下工作,我在所有地方都使用了CRLs,并为此引入了参数。
实际上,我甚至不得不将CRL显式地交给CrlClientOnline,因为默认情况下,iText只使用证书中的第一个CRL分发点,同时不支持LDAP。
底线:您可能还必须根据当前的iText限制来调整代码,或者改进iText代码本身,以可靠地生成具有任意有效输入的支持LTV的PDF.
https://stackoverflow.com/questions/42899185
复制相似问题