我是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);
}
答案 0 :(得分:0)
您的代码中的概念性问题是,在添加LTV信息后,您希望通过时间戳来完成整个过程。虽然这是您想要使用已经在LTV工作流程中的PDF所要做的事情,但您不希望使用PDF所有签名,您希望Adobe Reader将其声明为&#34; LTV启用&# 34。
(人们可以考虑Adobe的术语&#34;支持LTV&#34;意思是&#34;准备进入LTV工作流程,&#34;即尚未实际进入LTV工作流程LTV工作流程,但包括输入它所需的所有验证信息,无需任何进一步的麻烦。)
您的方法中还有其他问题,例如:您创建了两个单独的对象,这些对象通过dest
写入PdfSigner ps
,fos
通过PdfDocument pdfDoc
创建PdfWriter
。最后,你要么只能在文件中找到这些对象中的一个对象的输出,要么找到两者中的混合对象。
因此,这是我的旧iText 5方法addLtvNoTS
(从this answer)到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();
}
(EnableLtv方法addLtvNoTS
)
如您所见,我为时间戳和签名方法参数设置了LtvVerification.Level
值。
这是因为iText的方法LtvVerification.addVerification
仅为即时PDF签名和文档时间戳添加LTV信息,而不是针对已嵌入或现在添加的OCSP响应或CRL签名。
通常这没有问题,通常用于签署OCSP响应的证书以指示不需要撤销检查的方式标记,用于签署CRL的证书通常是隐式信任的CA证书本身。
但是,在我的测试签名的情况下,OCSP响应由签名签名,这些签名确实需要撤销检查。为了使事情在没有重要的额外编码的情况下工作,我全部使用了CRL,并为此引入了参数。
实际上,我甚至必须明确地将{CRI URL}提供给CrlClientOnline
,因为iText默认只使用证书中的第一个CRL分发点,同时不支持LDAP URL。
底线:您可能还必须围绕当前的iText限制调整代码,或者改进iText代码本身,以便在给定任意有效输入的情况下可靠地生成支持LTV的PDF ...