问题描述
我需要启用一个已签名的pdf LTV.签名证书具有三个级别的链(根/公共/个人).我知道有必要在pdf中添加证书的OCSP和CRL(根目录除外).
I need to make a signed pdf LTV enabled. Signing certificate has a chain with three levels (root / public / personal). I know that it is necessary to add OCSP and CRL of certificates in pdf (except root).
-
我可以为它使用基本的LtvVerification.addVerification()方法吗?如果我一次运行添加两个CRL,则结果PDF仅是第二个.如果我更改订单,是否还有第二个.如果我在两次运行中添加了CRL,它将以相同的方式结束-在pdf中,CRL将作为第二次添加.我以为添加"不会覆盖以前的状态.
Can I use for it basic LtvVerification.addVerification() method?If I add in one run two CRLs, in the result PDF is only a second. If i change order, is there again a second.If I add the CRL in two runs, it will end the same way - in pdf remains CRL added as a second.I thought the "add" will not overwrite the previous state..
如何正确使用方法LtvVerification.merge()?在添加第一个/第二个/两个CRL之前/之后?
How to properly use the method LtvVerification.merge()? Before/after adding first/second/both CRL?
或者我只能使用其他方法LtvVerification.addVerification(String signatureName,Collection ocsps,Collection crls,Collection certs)?
Or i can use only alternative method LtvVerification.addVerification(String signatureName, Collection ocsps, Collection crls, Collection certs)?
非常感谢您的提示.
源代码:
public void addLtv(String src, String dest) throws IOException, DocumentException, GeneralSecurityException
{
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
PdfReader r = new PdfReader(src);
System.out.println("Source file: " + src);
FileOutputStream fos = new FileOutputStream(dest);
PdfStamper stp = new PdfStamper(r, fos, '\0', true);
LtvVerification v = stp.getLtvVerification();
AcroFields fields = stp.getAcroFields();
ArrayList<String> names = fields.getSignatureNames();
String sigName = names.get(names.size() - 1);
System.out.println("found signature: " + sigName);
PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
//add LTV
OcspClient ocsp = new OcspClientBouncyCastle();
CrlClient crlClient1 = new CrlClientOnline("http://www.postsignum.cz/crl/psrootqca2.crl");
ArrayList<CrlClient> crllist = new ArrayList<CrlClient>();
crllist.add(crlClient1);
CrlClient crlClient2 = new CrlClientOnline("http://www.postsignum.cz/crl/pspublicca2.crl");
crllist.add(crlClient2);
System.out.println("crllist.size=" + crllist.size());
if (pkcs7.isTsp())
{
for (CrlClient crlclient : crllist)
{
if (v.addVerification(sigName, new OcspClientBouncyCastle(), crlclient,
LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
LtvVerification.Level.CRL,
LtvVerification.CertificateInclusion.NO)) {
System.out.println("crl " + crlclient.toString() + " added to timestamp");
}
}
} else{
for (String name : names)
{
for (int i = 0; i < crllist.size(); i++) {
if (v.addVerification(name, ocsp, crllist.get(i),
LtvVerification.CertificateOption.WHOLE_CHAIN,
LtvVerification.Level.CRL,
LtvVerification.CertificateInclusion.NO)) {
System.out.println("crl " + crllist.get(i).toString() + " added to " + name);
}
if (i > 0) {
System.out.println("found verification, merge");
v.merge();
}
}
}
}
stp.close();
}
推荐答案
如果要向LtvVerification.addVerification
提供多个CRL,则不要对每个CRL一次不调用该方法 ,但是使用所有CRL一次.
If you want to provide multiple CRLs to LtvVerification.addVerification
, you do not call that method once for each CRL but instead once with all CRLs.
为此CrlClientOnline
还接受多个URL:
For this CrlClientOnline
also accepts multiple URLs:
/**
* Creates a CrlClientOnline instance using one or more URLs.
*/
public CrlClientOnline(String... crls)
因此,通过改用此构造函数,我们可以简化并修复您的代码
Thus, by using this constructor instead we simplify and fix your code to
PdfReader r = new PdfReader(src);
FileOutputStream fos = new FileOutputStream(dest);
PdfStamper stp = new PdfStamper(r, fos, '\0', true);
LtvVerification v = stp.getLtvVerification();
AcroFields fields = stp.getAcroFields();
ArrayList<String> names = fields.getSignatureNames();
String sigName = names.get(names.size() - 1);
System.out.println("found signature: " + sigName);
PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
//add LTV
OcspClient ocsp = new OcspClientBouncyCastle();
CrlClient crlClient = new CrlClientOnline("http://www.postsignum.cz/crl/psrootqca2.crl", "http://www.postsignum.cz/crl/pspublicca2.crl");
if (pkcs7.isTsp())
{
if (v.addVerification(sigName, new OcspClientBouncyCastle(), crlClient,
LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
LtvVerification.Level.CRL,
LtvVerification.CertificateInclusion.NO))
{
System.out.println("crl " + crlClient.toString() + " added to timestamp");
}
}
else
{
for (String name : names)
{
if (v.addVerification(name, ocsp, crlClient,
LtvVerification.CertificateOption.WHOLE_CHAIN,
LtvVerification.Level.CRL,
LtvVerification.CertificateInclusion.NO))
{
System.out.println("crl " + crlClient.toString() + " added to " + name);
}
}
}
stp.close();
( AddLtvCrls.java ,方法addLtvFixed
)
(AddLtvCrls.java, method addLtvFixed
)
将其应用于您的示例文件,我们得到:
Applying it to your sample file, we get:
在某些背景下,LtvVerification.addVerification
将其具有的信息存储为所涉及签名的 验证信息.多次调用只会从上一次尝试计数时获得信息.
For some background, LtvVerification.addVerification
stores the information it has as the validation information required for the signature in question. Calling it multiple times results in the information only from the last attempt to count.
调用LtvVerification.merge
对此无济于事,因为它仅将旧版本中不同签名所需的验证信息合并到新的验证相关信息部分.
Calling LtvVerification.merge
does not help either here as it merely merges validation information required for different signatures from older revisions into the new validation related information section.
这篇关于启用iText LTV-如何添加更多CRL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!