已添加时间戳的DSS仍导致iText离线PAdES验证失败
使用iText离线验证PDF签名失败问题
问题场景
尝试用iText签名验证器以离线模式验证PDF文件,复现所需文件包括:
timestamped.pdfSwissSignRootCA.cerSwissSignTARootCA.cer
验证代码
var stream = new FileStream("timestamped.pdf", FileMode.Open); var ltvDocument = new PdfDocument(new PdfReader(stream)); var signatureUtil = new SignatureUtil(ltvDocument); var certificateParser = new X509CertificateParser(); var rootCAs = new List<IX509Certificate>(); foreach (var rootCaPath in new List<string>() { "SwissSignRootCA.cer", "SwissSignTARootCA.cer"}) { using var s2 = new FileStream(rootCaPath, FileMode.Open, FileAccess.Read); var cert = certificateParser.ReadCertificate(s2); Debug.Assert(cert != null); rootCAs.Add(new X509CertificateBC(cert)); } var validationProperties = new SignatureValidationProperties(); validationProperties.SetRevocationOnlineFetching(ValidatorContexts.All(), CertificateSources.All(), TimeBasedContexts.All(), SignatureValidationProperties.OnlineFetching.NEVER_FETCH); var validator = new ValidatorChainBuilder() .WithTrustedCertificates(rootCAs) .WithSignatureValidationProperties(validationProperties) .WithAdESReportAggregator(new DefaultAdESReportAggregator()) .BuildSignatureValidator(ltvDocument); var validationReport = validator.ValidateSignatures(); var failures = validationReport.GetFailures(); foreach (var f in failures) { Console.WriteLine($"{f.GetMessage()} : {f.GetExceptionCause()?.Message}"); }
错误信息
运行上述代码验证timestamped.pdf时,出现以下失败提示:
Certificate revocation status cannot be checked: no revocation data available or the status cannot be determined. : Certificate revocation status cannot be checked: no revocation data available or the status cannot be determined. :
若将验证模式改为允许在线获取(而非OnlineFetching.NEVER_FETCH),则PDF可验证通过。
预期离线验证成功的依据
- 该PDF包含带有OCSP和CRL数据的DSS验证材料;
- 包含DSS的修订版本已被后续文档时间戳覆盖;
- 后续文档时间戳可通过提供的根CA证书验证;
- 嵌入的OCSP/CRL对象当前已过期,但在后续文档时间戳生成时仍有效。
根据PAdES-LTA/PAdES-DTS-A格式验证逻辑,后续文档时间戳可证明嵌入验证材料的存在性,因此OCSP/CRL数据无需在当前验证时间仍有效。
环境信息
- .NET: net10.0
- iText: 9.6.0
- itext.bouncy-castle-adapter: 9.6.0
问题分析与解决思路
iText 9.x的离线签名验证逻辑默认会严格检查撤销数据的当前有效性,即便存在后续时间戳证明撤销数据在当时有效,也可能因当前已过期判定为无可用撤销数据。
要实现符合PAdES-LTA/DTS-A规范的离线验证,需明确配置验证器使用时间戳覆盖时的快照时间校验撤销数据有效性,而非当前时间。可调整SignatureValidationProperties,指定针对带时间戳的场景使用签名时间作为校验基准:
// 修改验证属性,适配时间戳覆盖的场景 validationProperties.SetRevocationOnlineFetching(ValidatorContexts.Timestamped(), CertificateSources.All(), TimeBasedContexts.SignatureTime(), SignatureValidationProperties.OnlineFetching.NEVER_FETCH);
另外,可先通过代码确认文档中DSS容器是否被正确识别:
var dss = ltvDocument.GetCatalog().GetPdfObject(PdfName.DSS); if (dss != null) { Console.WriteLine("文档包含DSS容器"); }
若调整配置后仍无法解决,可能是iText 9.6.0版本在离线LTA验证逻辑上存在bug,建议升级到最新版本,或尝试手动提取DSS中的撤销数据并绑定到验证上下文。
内容的提问来源于stack exchange,提问作者craffael
相关产品推荐
相关产品推荐

