使用ESig DSS 5.12.1验证签名始终返回INDETERMINATE问题求助
DSS 5.12.1签名验证返回INDETERMINATE(NO_CERTIFICATE_CHAIN_FOUND)问题排查
问题描述
我正尝试使用欧盟委员会发起的Digital Signature Service (DSS) 5.12.1版本库,验证带数字签名的PDF和XML文件的电子签名。我采用了dss-documentation PDF中给出的代码:
byte[] binaryPdf = Base64.getDecoder().decode(base64EncodedDocument); CommonTrustedCertificateSource trustedCertSource = new CommonTrustedCertificateSource(); CertificateVerifier cv = new CommonTrustedCertificateVerifier(); cv.setAIASource(new DefaultAIASource()); cv.setOcspSource(new OnlineOCSPSource()); cv.setCrlSource(new OnlineCRLSource()); cv.addTrustedCertSources(trustedCertSource); DSSDocument document = new InMemoryDocument(binaryPdf, shortFileName); SignedDocumentValidator documentValidator = SignedDocumentValidator.fromDocument(document); documentValidator.setCertificateVerifier(cv); UserFriendlyIdentifierProvider userFriendlyIdentifierProvider = new UserFriendlyIdentifierProvider(); documentValidator.setTokenIdentifierProvider(userFriendlyIdentifierProvider); Reports reports = documentValidator.validateDocument();但我的应用始终返回INDETERMINATE指示,子提示为NO_CERTIFICATE_CHAIN_FOUND(在CertificateChain的Certificate元素中可见),无法找到信任锚点。使用同版本的示例应用验证同一文档时,却能得到预期的TOTAL_PASSED指示,且我的应用具备网络访问权限。
问题根源及解决步骤
1. 信任证书源未加载根证书
你创建了CommonTrustedCertificateSource但未添加任何信任锚(根CA证书)。示例应用默认会加载系统信任库或DSS内置的信任证书集合,而你的代码里trustedCertSource是空的,导致验证时找不到信任锚。
解决方式:
- 加载系统默认信任库:
TrustedCertificateSource systemTrustedSource = new SystemCertificateSource(); cv.addTrustedCertSources(systemTrustedSource); - 或者加载DSS提供的欧盟信任列表(需确保依赖包含
dss-tsl模块):TLSLoader tlsLoader = new TLSLoader(); TrustedCertificateSource tlsTrustedSource = tlsLoader.loadTrustServiceList(); cv.addTrustedCertSources(tlsTrustedSource); - 也可以手动添加特定根证书:
DSSDocument certFile = new FileDocument(new File("path/to/rootCA.cer")); X509Certificate rootCert = DSSUtils.loadCertificate(certFile.openStream()); trustedCertSource.addCertificate(rootCert);
2. 启用未信任链的吊销检查优化
部分场景下,中间证书缺失会导致无法构建完整链,可通过以下配置允许验证器通过AIA自动检索中间证书:
cv.setCheckRevocationForUntrustedChains(true);
3. 对齐示例应用的信任源配置
示例应用通常会同时加载多种信任源(如系统库+TSL列表),你可以参考DSS示例代码(如ValidationController类)的初始化逻辑,确保你的信任源配置和示例一致。
4. 调试证书链详情
通过以下代码打印证书链的详细信息,明确缺失的证书环节:
Reports reports = documentValidator.validateDocument(); SignatureValidationReport signatureReport = reports.getSignatureValidationReport(); for (SignatureValidationResult result : signatureReport.getSignatureValidationResults()) { CertificateChainValidationResult chainResult = result.getCertificateChainValidationResult(); System.out.println("证书链状态:" + chainResult.getStatus()); for (DSSException exception : chainResult.getErrors()) { System.out.println("错误详情:" + exception.getMessage()); } for (CertificateToken cert : chainResult.getCertificateChain()) { System.out.println("证书主题:" + cert.getSubject().getRFC2253()); } }
内容的提问来源于stack exchange,提问作者goran
相关产品推荐
相关产品推荐

