gpt4 book ai didi

java - 如何在启用嵌入式时间戳和 LTV 的情况下签署 PDF?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:49:25 25 4
gpt4 key购买 nike

我正在尝试签署启用了时间戳和 LTV 的 pdf,以便它在 Adob​​e Reader 中显示如下:

Correct signing

用英语表示“签名包含嵌入的时间戳”和“签名启用了 LTV”。这是我正在使用的代码:

PrivateKey pk = // get pk from an encrypting certificate created using encrypting file system
Certificate[] chain = ks.getCertificateChain(alias);

PdfReader reader = new PdfReader(src);
FileOutputStream fout = new FileOutputStream(dest);
PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');

PdfSignatureAppearance sap = stp.getSignatureAppearance();

ExternalSignature signature = new PrivateKeySignature(pk, "SHA-512", "SunMSCAPI");
TSAClient tsc = null;
String url = // TSA URL
tsc = new TSAClientBouncyCastle(url, null, null, 4096, "SHA-512");

List<CrlClient> crlList = new ArrayList<>();
crlList.add(new CrlClientOnline(chain));

ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(sap, digest, signature, chain, crlList, null, tsc, 0, CryptoStandard.CMS);

基于 this answer ,我需要一种方法将 TSA 证书的 CRL 获取到 CrlList,但是..我怎样才能获得 TSA 证书?我是否需要向 TSA 发出 timestamp-query 请求并读取响应,然后将其添加到 CrlList?请注意,这已在 MakeSignature.signDetached 调用 sgn.getEncodedPKCS7 时完成。请注意,我使用的是免费的 TSA 服务器。

这是在 Adob​​e Reader 中使用上面的代码显示的内容。签名详情: enter image description here

时间戳详情: enter image description here

TSA 证书详情: enter image description here


更新

因为它是一个免费的 TSA 服务器,我只需要在 Adob​​e Trusted Certificates 中添加 TSA 服务器证书,现在就可以使用了。 但是,我已经使用智能卡对文档进行了另一项测试,这就是我得到的结果(我已将根证书添加到 Adob​​e 的受信任证书中):

签名详情:

enter image description here

签名证书详细信息:

enter image description here

基于 this link ,启用 LTV 意味着验证文件所需的所有信息(减去根证书)都包含在 PDF 中。因此,如果 PDF 已正确签名并包含所有必要的证书和每个证书的有效 CRL 或 OSCP 响应,并且如果它包含基于 CRL 和 OCSP 的签名,而不仅仅是签名证书,则 PDF 是启用 LTV 的。看起来我满足了所有这些要求,还是我遗漏了什么?如果是这样,我怎么知道缺少什么才能获得支持 LTV 的 pdf?

最佳答案

首先,根据@mkl 的评论,我将 TSA 服务器证书添加到 Adob​​e Trusted Certificates,以便消息

the signature includes an embedded timestamp but it could not be verified

成为

the signature includes an embedded timestamp

并解决

Signature is not LTV enabled and will expire after (...)

我可以注意到使用

List<CrlClient> crlList = new ArrayList<>();
crlList.add(new CrlClientOnline(chain));

有一些 CRL(一些证书有多个分发点)没有被添加——使得 pdf LTV 没有被启用。为了解决这个问题,我这样做了:

// long term validation (LTV)
List<CrlClient> crlList = new ArrayList<>();

for(Certificate cert : chain) {
X509Certificate c = (X509Certificate)cert;
List<String> crls = this.getCrlDistributionPoints(c);
if(crls != null && !crls.isEmpty()) {
crlList.add(new CrlClientOnline(crls.toArray(new String[crls.size()])));
}
}

private List<String> getCrlDistributionPoints(final X509Certificate cert) throws Exception {
final byte[] crldpExt = cert.getExtensionValue(X509Extension.cRLDistributionPoints.getId());
if (crldpExt == null) {
final List<String> emptyList = new ArrayList<String>();
return emptyList;
}
ASN1InputStream oAsnInStream = null;
ASN1InputStream oAsnInStream2 = null;
List<String> crlUrls = new ArrayList<String>();

try {
oAsnInStream = new ASN1InputStream(new ByteArrayInputStream(crldpExt));
final ASN1Object derObjCrlDP = oAsnInStream.readObject();
final DEROctetString dosCrlDP = (DEROctetString) derObjCrlDP;
final byte[] crldpExtOctets = dosCrlDP.getOctets();
oAsnInStream2 = new ASN1InputStream(new ByteArrayInputStream(crldpExtOctets));
final ASN1Object derObj2 = oAsnInStream2.readObject();
final CRLDistPoint distPoint = CRLDistPoint.getInstance(derObj2);
for (final DistributionPoint dp : distPoint.getDistributionPoints()) {
final DistributionPointName dpn = dp.getDistributionPoint();
// Look for URIs in fullName
if (dpn != null) {
if (dpn.getType() == DistributionPointName.FULL_NAME) {
final GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
// Look for an URI
for (int j = 0; j < genNames.length; j++) {
if (genNames[j].getTagNo() == GeneralName.uniformResourceIdentifier) {
final String url = DERIA5String.getInstance(genNames[j].getName()).getString();
crlUrls.add(url);
}
}
}
}
}
} catch(IOException e) {
throw new Exception(e.getMessage(), e);
} finally {
IOUtils.closeQuietly(oAsnInStream);
IOUtils.closeQuietly(oAsnInStream2);
}

return crlUrls;
}

关于java - 如何在启用嵌入式时间戳和 LTV 的情况下签署 PDF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46321086/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com